remove ports/esp8266
This commit is contained in:
parent
41ef2ab591
commit
7692e06230
1
ports/esp8266/.gitignore
vendored
1
ports/esp8266/.gitignore
vendored
@ -1 +0,0 @@
|
||||
build-*/
|
@ -1,280 +0,0 @@
|
||||
# Select the board to build for: if not given on the command line,
|
||||
# then default to PYBV10.
|
||||
BOARD ?= feather_huzzah
|
||||
ifeq ($(wildcard boards/$(BOARD)/.),)
|
||||
$(error Invalid BOARD specified)
|
||||
endif
|
||||
|
||||
# If the build directory is not given, make it reflect the board name.
|
||||
BUILD ?= build-$(BOARD)
|
||||
|
||||
include ../../py/mkenv.mk
|
||||
|
||||
# qstr definitions (must come before including py.mk)
|
||||
QSTR_DEFS = qstrdefsport.h #$(BUILD)/pins_qstr.h
|
||||
|
||||
MICROPY_PY_USSL = 1
|
||||
MICROPY_SSL_AXTLS = 1
|
||||
MICROPY_FATFS = 1
|
||||
MICROPY_PY_BTREE = 1
|
||||
BTREE_DEFS_EXTRA = -DDEFPSIZE=1024 -DMINCACHE=3
|
||||
|
||||
FROZEN_DIR ?= scripts
|
||||
FROZEN_MPY_DIR ?= modules
|
||||
|
||||
# include py core make definitions
|
||||
include $(TOP)/py/py.mk
|
||||
|
||||
FWBIN = $(BUILD)/firmware.bin
|
||||
PORT ?= /dev/ttyACM0
|
||||
BAUD ?= 115200
|
||||
FLASH_MODE ?= qio
|
||||
FLASH_SIZE ?= detect
|
||||
CROSS_COMPILE = xtensa-lx106-elf-
|
||||
ESP_SDK = $(shell $(CC) -print-sysroot)/usr
|
||||
ESPTOOL = esptool.py
|
||||
|
||||
INC += -I.
|
||||
INC += -I$(TOP)
|
||||
INC += -I$(BUILD)
|
||||
INC += -I$(ESP_SDK)/include
|
||||
|
||||
# UART for "os" messages. 0 is normal UART as used by MicroPython REPL,
|
||||
# 1 is debug UART (tx only), -1 to disable.
|
||||
UART_OS = 0
|
||||
|
||||
CFLAGS_XTENSA = -fsingle-precision-constant -Wdouble-promotion \
|
||||
-D__ets__ -DICACHE_FLASH \
|
||||
-fno-inline-functions \
|
||||
-Wl,-EL -mlongcalls -mtext-section-literals -mforce-l32 \
|
||||
-DLWIP_OPEN_SRC
|
||||
|
||||
CFLAGS = $(INC) -Wall -Wpointer-arith -Werror -Wno-strict-aliasing -std=gnu99 -nostdlib -DUART_OS=$(UART_OS) \
|
||||
$(CFLAGS_XTENSA) $(CFLAGS_MOD) $(COPT) $(CFLAGS_EXTRA)
|
||||
|
||||
LDSCRIPT = esp8266.ld
|
||||
LDFLAGS = -nostdlib -T $(LDSCRIPT) -Map=$(@:.elf=.map) --cref
|
||||
LIBS = -L$(ESP_SDK)/lib -lmain -ljson -llwip_open -lpp -lnet80211 -lwpa -lphy -lnet80211 $(LDFLAGS_MOD)
|
||||
|
||||
LIBGCC_FILE_NAME = $(shell $(CC) $(CFLAGS) -print-libgcc-file-name)
|
||||
LIBS += -L$(dir $(LIBGCC_FILE_NAME)) -lgcc
|
||||
|
||||
# Debugging/Optimization
|
||||
ifeq ($(DEBUG), 1)
|
||||
CFLAGS += -g
|
||||
COPT = -O0
|
||||
else
|
||||
CFLAGS += -fdata-sections -ffunction-sections
|
||||
COPT += -Os -DNDEBUG
|
||||
LDFLAGS += --gc-sections
|
||||
endif
|
||||
|
||||
SRC_C = \
|
||||
strtoll.c \
|
||||
main.c \
|
||||
help.c \
|
||||
esp_mphal.c \
|
||||
esp_init_data.c \
|
||||
gccollect.c \
|
||||
lexerstr32.c \
|
||||
uart.c \
|
||||
esppwm.c \
|
||||
espneopixel.c \
|
||||
intr.c \
|
||||
modpyb.c \
|
||||
modmachine.c \
|
||||
machine_pin.c \
|
||||
machine_pwm.c \
|
||||
machine_rtc.c \
|
||||
machine_adc.c \
|
||||
machine_uart.c \
|
||||
machine_wdt.c \
|
||||
machine_hspi.c \
|
||||
modesp.c \
|
||||
modnetwork.c \
|
||||
ets_alt_task.c \
|
||||
fatfs_port.c \
|
||||
posix_helpers.c \
|
||||
hspi.c \
|
||||
boards/$(BOARD)/pins.c \
|
||||
supervisor/stub/stack.c \
|
||||
supervisor/shared/translate.c \
|
||||
$(SRC_MOD)
|
||||
|
||||
SRC_COMMON_HAL = \
|
||||
microcontroller/__init__.c \
|
||||
microcontroller/Pin.c \
|
||||
microcontroller/Processor.c \
|
||||
analogio/__init__.c \
|
||||
analogio/AnalogIn.c \
|
||||
analogio/AnalogOut.c \
|
||||
digitalio/__init__.c \
|
||||
digitalio/DigitalInOut.c \
|
||||
pulseio/__init__.c \
|
||||
pulseio/PulseIn.c \
|
||||
pulseio/PulseOut.c \
|
||||
pulseio/PWMOut.c \
|
||||
busio/__init__.c \
|
||||
busio/SPI.c \
|
||||
busio/UART.c \
|
||||
multiterminal/__init__.c \
|
||||
neopixel_write/__init__.c \
|
||||
os/__init__.c \
|
||||
time/__init__.c \
|
||||
board/__init__.c
|
||||
|
||||
|
||||
# These don't have corresponding files in each port but are still located in
|
||||
# shared-bindings to make it clear what the contents of the modules are.
|
||||
SRC_BINDINGS_ENUMS = \
|
||||
digitalio/Direction.c \
|
||||
digitalio/DriveMode.c \
|
||||
digitalio/Pull.c \
|
||||
math/__init__.c \
|
||||
microcontroller/RunMode.c \
|
||||
util.c
|
||||
|
||||
SRC_COMMON_HAL_EXPANDED = $(addprefix shared-bindings/, $(SRC_COMMON_HAL)) \
|
||||
$(addprefix shared-bindings/, $(SRC_BINDINGS_ENUMS)) \
|
||||
$(addprefix common-hal/, $(SRC_COMMON_HAL))
|
||||
SRC_SHARED_MODULE = \
|
||||
bitbangio/__init__.c \
|
||||
bitbangio/I2C.c \
|
||||
bitbangio/OneWire.c \
|
||||
bitbangio/SPI.c \
|
||||
busio/I2C.c \
|
||||
busio/OneWire.c \
|
||||
multiterminal/__init__.c \
|
||||
os/__init__.c \
|
||||
random/__init__.c \
|
||||
struct/__init__.c
|
||||
|
||||
SRC_SHARED_MODULE_EXPANDED = $(addprefix shared-bindings/, $(SRC_SHARED_MODULE)) \
|
||||
$(addprefix shared-module/, $(SRC_SHARED_MODULE))
|
||||
|
||||
EXTMOD_SRC_C = $(addprefix extmod/,\
|
||||
modlwip.c \
|
||||
modonewire.c \
|
||||
)
|
||||
|
||||
LIB_SRC_C = $(addprefix lib/,\
|
||||
libc/string0.c \
|
||||
libm/math.c \
|
||||
libm/fmodf.c \
|
||||
libm/nearbyintf.c \
|
||||
libm/ef_sqrt.c \
|
||||
libm/kf_rem_pio2.c \
|
||||
libm/kf_sin.c \
|
||||
libm/kf_cos.c \
|
||||
libm/kf_tan.c \
|
||||
libm/ef_rem_pio2.c \
|
||||
libm/sf_sin.c \
|
||||
libm/sf_cos.c \
|
||||
libm/sf_tan.c \
|
||||
libm/sf_frexp.c \
|
||||
libm/sf_modf.c \
|
||||
libm/sf_ldexp.c \
|
||||
libm/asinfacosf.c \
|
||||
libm/atanf.c \
|
||||
libm/atan2f.c \
|
||||
mp-readline/readline.c \
|
||||
netutils/netutils.c \
|
||||
timeutils/timeutils.c \
|
||||
utils/buffer_helper.c \
|
||||
utils/context_manager_helpers.c \
|
||||
utils/pyexec.c \
|
||||
utils/interrupt_char.c \
|
||||
utils/sys_stdio_mphal.c \
|
||||
)
|
||||
|
||||
ifeq ($(MICROPY_FATFS), 1)
|
||||
LIB_SRC_C += \
|
||||
lib/oofatfs/ff.c \
|
||||
lib/oofatfs/option/unicode.c
|
||||
endif
|
||||
|
||||
DRIVERS_SRC_C = $(addprefix drivers/,\
|
||||
bus/softspi.c \
|
||||
)
|
||||
|
||||
SRC_S = \
|
||||
gchelper.s \
|
||||
|
||||
OBJ =
|
||||
OBJ += $(PY_O)
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_S:.s=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_COMMON_HAL_EXPANDED:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(SRC_SHARED_MODULE_EXPANDED:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(STM_SRC_C:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(EXTMOD_SRC_C:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(LIB_SRC_C:.c=.o))
|
||||
OBJ += $(addprefix $(BUILD)/, $(DRIVERS_SRC_C:.c=.o))
|
||||
|
||||
# List of sources for qstr extraction
|
||||
SRC_QSTR += $(SRC_C) $(SRC_COMMON_HAL_EXPANDED) $(SRC_SHARED_MODULE_EXPANDED) $(STM_SRC_C) $(EXTMOD_SRC_C) $(DRIVERS_SRC_C)
|
||||
# Append any auto-generated sources that are needed by sources listed in SRC_QSTR
|
||||
SRC_QSTR_AUTO_DEPS +=
|
||||
|
||||
all:
|
||||
@echo "CircuitPython 4.0.0 and later do not support esp8266 boards."
|
||||
|
||||
CONFVARS_FILE = $(BUILD)/confvars
|
||||
|
||||
ifeq ($(wildcard $(CONFVARS_FILE)),)
|
||||
$(shell $(MKDIR) -p $(BUILD))
|
||||
$(shell echo $(FROZEN_DIR) $(UART_OS) > $(CONFVARS_FILE))
|
||||
else ifneq ($(shell cat $(CONFVARS_FILE)), $(FROZEN_DIR) $(UART_OS))
|
||||
$(shell echo $(FROZEN_DIR) $(UART_OS) > $(CONFVARS_FILE))
|
||||
endif
|
||||
|
||||
$(BUILD)/uart.o: $(CONFVARS_FILE)
|
||||
|
||||
FROZEN_EXTRA_DEPS = $(CONFVARS_FILE)
|
||||
|
||||
.PHONY: deploy
|
||||
|
||||
deploy: $(FWBIN)
|
||||
$(ECHO) "Writing $< to the board"
|
||||
$(Q)$(ESPTOOL) --port $(PORT) --baud $(BAUD) write_flash --verify --flash_size=$(FLASH_SIZE) --flash_mode=$(FLASH_MODE) 0 $<
|
||||
|
||||
erase:
|
||||
$(ECHO) "Erase flash"
|
||||
$(Q)$(ESPTOOL) --port $(PORT) --baud $(BAUD) erase_flash
|
||||
|
||||
reset:
|
||||
echo -e "\r\nimport machine; machine.reset()\r\n" >$(PORT)
|
||||
|
||||
$(FWBIN): $(BUILD)/firmware.elf
|
||||
$(ECHO) "Create $@"
|
||||
$(Q)$(ESPTOOL) elf2image $^
|
||||
$(Q)$(PYTHON) makeimg.py $(BUILD)/firmware.elf-0x00000.bin $(BUILD)/firmware.elf-0x[0-5][1-f]000.bin $@
|
||||
|
||||
|
||||
$(BUILD)/firmware.elf: $(OBJ)
|
||||
$(STEPECHO) "LINK $@"
|
||||
$(Q)$(LD) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||
$(Q)$(SIZE) $@
|
||||
|
||||
512k:
|
||||
$(MAKE) LDSCRIPT=esp8266_512k.ld CFLAGS_EXTRA='-DMP_CONFIGFILE="<mpconfigport_512k.h>"' MICROPY_FATFS=0 MICROPY_PY_BTREE=0
|
||||
|
||||
ota:
|
||||
rm -f $(BUILD)/firmware.elf $(BUILD)/firmware.elf*.bin
|
||||
$(MAKE) LDSCRIPT=esp8266_ota.ld FWBIN=$(BUILD)/firmware-ota.bin
|
||||
|
||||
include $(TOP)/py/mkrules.mk
|
||||
|
||||
axtls: $(BUILD)/libaxtls.a
|
||||
|
||||
$(BUILD)/libaxtls.a:
|
||||
cd $(TOP)/lib/axtls; cp config/upyconfig config/.config
|
||||
cd $(TOP)/lib/axtls; $(MAKE) ssl/version.h
|
||||
cd $(TOP)/lib/axtls; $(MAKE) oldconfig -B
|
||||
cd $(TOP)/lib/axtls; $(MAKE) clean
|
||||
cd $(TOP)/lib/axtls; $(MAKE) all CC="$(CC)" LD="$(LD)" AR="$(AR)" CFLAGS_EXTRA="$(CFLAGS_XTENSA) -Dabort=abort_ -DRT_MAX_PLAIN_LENGTH=1024 -DRT_EXTRA=4096"
|
||||
cp $(TOP)/lib/axtls/_stage/libaxtls.a $@
|
||||
|
||||
clean-modules:
|
||||
git clean -f -d modules
|
||||
rm -f $(BUILD)/frozen*.c
|
@ -1,171 +0,0 @@
|
||||
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.
|
||||
|
||||
Supported features include:
|
||||
- REPL (Python prompt) over UART0.
|
||||
- Garbage collector, exceptions.
|
||||
- Unicode support.
|
||||
- Builtin modules: gc, array, collections, io, struct, sys, esp, network,
|
||||
many more.
|
||||
- Arbitrary-precision long integers and 30-bit precision floats.
|
||||
- WiFi support.
|
||||
- Sockets using modlwip.
|
||||
- GPIO and bit-banging I2C, SPI support.
|
||||
- 1-Wire and WS2812 (aka Neopixel) protocols support.
|
||||
- Internal filesystem using the flash.
|
||||
- WebREPL over WiFi from a browser (clients at https://github.com/micropython/webrepl).
|
||||
- Modules for HTTP, MQTT, many other formats and protocols via
|
||||
https://github.com/micropython/micropython-lib .
|
||||
|
||||
Work-in-progress documentation is available at
|
||||
http://docs.micropython.org/en/latest/esp8266/ .
|
||||
|
||||
Build instructions
|
||||
------------------
|
||||
|
||||
The tool chain required for the build is the OpenSource ESP SDK, which can be
|
||||
found at <https://github.com/pfalcon/esp-open-sdk>. Clone this repository and
|
||||
run `make` in its directory to build and install the SDK locally. Make sure
|
||||
to add toolchain bin directory to your PATH. Read esp-open-sdk's README for
|
||||
additional important information on toolchain setup.
|
||||
|
||||
Travis builds, including releases are actually built using a specific
|
||||
esp-open-sdk binary. The location of the binary can be seen in the
|
||||
`.travis.yml` in the top-level directory of CircuitPython. This may be ahead
|
||||
of or behind the pfalcon repository, depending on the specific needs of
|
||||
CircuitPython. If your local system is binary-compatible with Travis
|
||||
(most Ubuntu and Debian based systems are), you can download the binary and
|
||||
skip building it locally.
|
||||
|
||||
Add the external dependencies to the MicroPython repository checkout:
|
||||
```bash
|
||||
$ git submodule update --init
|
||||
```
|
||||
See the README in the repository root for more information about external
|
||||
dependencies.
|
||||
|
||||
The MicroPython cross-compiler must be built to pre-compile some of the
|
||||
built-in scripts to bytecode. This can be done using:
|
||||
```bash
|
||||
$ make -C mpy-cross
|
||||
```
|
||||
|
||||
Then, to build MicroPython for the ESP8266, just run:
|
||||
```bash
|
||||
$ cd ports/esp8266
|
||||
$ make axtls
|
||||
$ make
|
||||
```
|
||||
This will produce binary images in the `build/` subdirectory. If you install
|
||||
MicroPython to your module for the first time, or after installing any other
|
||||
firmware, you should erase flash completely:
|
||||
|
||||
```
|
||||
esptool.py --port /dev/ttyXXX erase_flash
|
||||
```
|
||||
|
||||
Erase flash also as a troubleshooting measure, if a module doesn't behave as
|
||||
expected.
|
||||
|
||||
To flash MicroPython image to your ESP8266, use:
|
||||
```bash
|
||||
$ make deploy
|
||||
```
|
||||
This will use the `esptool.py` script to download the images. You must have
|
||||
your ESP module in the bootloader mode, and connected to a serial port on your PC.
|
||||
The default serial port is `/dev/ttyACM0`, flash mode is `qio` and flash size is
|
||||
`detect` (auto-detect based on Flash ID). To specify other values, use, eg (note
|
||||
that flash size is in megabits):
|
||||
```bash
|
||||
$ make PORT=/dev/ttyUSB0 FLASH_MODE=qio FLASH_SIZE=32m deploy
|
||||
```
|
||||
|
||||
The image produced is `build/firmware-combined.bin`, to be flashed at 0x00000.
|
||||
|
||||
__512KB FlashROM version__
|
||||
|
||||
The normal build described above requires modules with at least 1MB of FlashROM
|
||||
onboard. There's a special configuration for 512KB modules, which can be
|
||||
built with `make 512k`. This configuration is highly limited, lacks filesystem
|
||||
support, WebREPL, and has many other features disabled. It's mostly suitable
|
||||
for advanced users who are interested to fine-tune options to achieve a required
|
||||
setup. If you are an end user, please consider using a module with at least 1MB
|
||||
of FlashROM.
|
||||
|
||||
First start
|
||||
-----------
|
||||
|
||||
Be sure to change ESP8266's WiFi access point password ASAP, see below.
|
||||
|
||||
__Serial prompt__
|
||||
|
||||
You can access the REPL (Python prompt) over UART (the same as used for
|
||||
programming).
|
||||
- Baudrate: 115200
|
||||
|
||||
Run `help()` for some basic information.
|
||||
|
||||
__WiFi__
|
||||
|
||||
Initially, the device configures itself as a WiFi access point (AP).
|
||||
- ESSID: MicroPython-xxxxxx (x’s are replaced with part of the MAC address).
|
||||
- Password: micropythoN (note the upper-case N).
|
||||
- IP address of the board: 192.168.4.1.
|
||||
- DHCP-server is activated.
|
||||
- Please be sure to change the password to something non-guessable
|
||||
immediately. `help()` gives information how.
|
||||
|
||||
__WebREPL__
|
||||
|
||||
Python prompt over WiFi, connecting through a browser.
|
||||
- Hosted at http://micropython.org/webrepl.
|
||||
- GitHub repository https://github.com/micropython/webrepl.
|
||||
Please follow the instructions there.
|
||||
|
||||
__upip__
|
||||
|
||||
The ESP8266 port comes with builtin `upip` package manager, which can
|
||||
be used to install additional modules (see the main README for more
|
||||
information):
|
||||
|
||||
```
|
||||
>>> import upip
|
||||
>>> upip.install("micropython-pystone_lowmem")
|
||||
[...]
|
||||
>>> import pystone_lowmem
|
||||
>>> pystone_lowmem.main()
|
||||
```
|
||||
|
||||
Downloading and installing packages may requite a lot of free memory,
|
||||
if you get an error, retry immediately after the hard reset.
|
||||
|
||||
Documentation
|
||||
-------------
|
||||
|
||||
More detailed documentation and instructions can be found at
|
||||
http://docs.micropython.org/en/latest/esp8266/ , which includes Quick
|
||||
Reference, Tutorial, General Information related to ESP8266 port, and
|
||||
to MicroPython in general.
|
||||
|
||||
Troubleshooting
|
||||
---------------
|
||||
|
||||
While the port is in beta, it's known to be generally stable. If you
|
||||
experience strange bootloops, crashes, lockups, here's a list to check against:
|
||||
|
||||
- You didn't erase flash before programming MicroPython firmware.
|
||||
- Firmware can be occasionally flashed incorrectly. Just retry. Recent
|
||||
esptool.py versions have --verify option.
|
||||
- Power supply you use doesn't provide enough power for ESP8266 or isn't
|
||||
stable enough.
|
||||
- A module/flash may be defective (not unheard of for cheap modules).
|
||||
|
||||
Please consult dedicated ESP8266 forums/resources for hardware-related
|
||||
problems.
|
||||
|
||||
Additional information may be available by the documentation links above.
|
@ -1,48 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* 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 "common-hal/microcontroller/__init__.h"
|
||||
|
||||
STATIC const mp_rom_map_elem_t board_global_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&pin_TOUT) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_GPIO16), MP_ROM_PTR(&pin_XPD_DCDC) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_GPIO14), MP_ROM_PTR(&pin_MTMS) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_SCK), MP_ROM_PTR(&pin_MTMS) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_GPIO12), MP_ROM_PTR(&pin_MTDI) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_MISO), MP_ROM_PTR(&pin_MTDI) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_GPIO13), MP_ROM_PTR(&pin_MTCK) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_MOSI), MP_ROM_PTR(&pin_MTCK) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_GPIO15), MP_ROM_PTR(&pin_MTDO) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_GPIO2), MP_ROM_PTR(&pin_GPIO2) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_GPIO0), MP_ROM_PTR(&pin_GPIO0) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_GPIO4), MP_ROM_PTR(&pin_GPIO4) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_SDA), MP_ROM_PTR(&pin_GPIO4) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_RX), MP_ROM_PTR(&pin_U0RXD) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_TX), MP_ROM_PTR(&pin_U0TXD) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_GPIO5), MP_ROM_PTR(&pin_DVDD) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_SCL), MP_ROM_PTR(&pin_DVDD) },
|
||||
};
|
||||
MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table);
|
@ -1,67 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* 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/nlr.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/binary.h"
|
||||
#include "py/mphal.h"
|
||||
#include "common-hal/microcontroller/__init__.h"
|
||||
#include "shared-bindings/analogio/AnalogIn.h"
|
||||
#include "supervisor/shared/translate.h"
|
||||
|
||||
#include "user_interface.h"
|
||||
|
||||
void common_hal_analogio_analogin_construct(analogio_analogin_obj_t* self,
|
||||
const mcu_pin_obj_t *pin) {
|
||||
if (pin != &pin_TOUT) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, translate("Pin %q does not have ADC capabilities"), pin->name));
|
||||
}
|
||||
claim_pin(pin);
|
||||
}
|
||||
|
||||
bool common_hal_analogio_analogin_deinited(analogio_analogin_obj_t* self) {
|
||||
return self->deinited;
|
||||
}
|
||||
|
||||
void common_hal_analogio_analogin_deinit(analogio_analogin_obj_t* self) {
|
||||
if (common_hal_analogio_analogin_deinited(self)) {
|
||||
return;
|
||||
}
|
||||
reset_pin(&pin_TOUT);
|
||||
self->deinited = true;
|
||||
}
|
||||
|
||||
uint16_t common_hal_analogio_analogin_get_value(analogio_analogin_obj_t *self) {
|
||||
// ADC is 10 bit so shift by 6 to make it 16-bit.
|
||||
return system_adc_read() << 6;
|
||||
}
|
||||
|
||||
float common_hal_analogio_analogin_get_reference_voltage(analogio_analogin_obj_t *self) {
|
||||
return 1.0f;
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Scott Shawcroft
|
||||
*
|
||||
* 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_ESP8266_COMMON_HAL_ANALOGIO_ANALOGIN_H
|
||||
#define MICROPY_INCLUDED_ESP8266_COMMON_HAL_ANALOGIO_ANALOGIN_H
|
||||
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
bool deinited;
|
||||
} analogio_analogin_obj_t;
|
||||
|
||||
#endif // MICROPY_INCLUDED_ESP8266_COMMON_HAL_ANALOGIO_ANALOGIN_H
|
@ -1,51 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 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 "shared-bindings/analogio/AnalogOut.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/runtime.h"
|
||||
#include "supervisor/shared/translate.h"
|
||||
|
||||
void common_hal_analogio_analogout_construct(analogio_analogout_obj_t* self,
|
||||
const mcu_pin_obj_t *pin) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError,
|
||||
translate("No hardware support for analog out.")));
|
||||
}
|
||||
|
||||
bool common_hal_analogio_analogout_deinited(analogio_analogout_obj_t *self) {
|
||||
return true;
|
||||
}
|
||||
|
||||
void common_hal_analogio_analogout_deinit(analogio_analogout_obj_t *self) {
|
||||
}
|
||||
|
||||
void common_hal_analogio_analogout_set_value(analogio_analogout_obj_t *self,
|
||||
uint16_t value) {
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Scott Shawcroft
|
||||
*
|
||||
* 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_ESP8266_COMMON_HAL_ANALOGIO_ANALOGOUT_H
|
||||
#define MICROPY_INCLUDED_ESP8266_COMMON_HAL_ANALOGIO_ANALOGOUT_H
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
// Not supported, throws error on construction.
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
} analogio_analogout_obj_t;
|
||||
|
||||
#endif // MICROPY_INCLUDED_ESP8266_COMMON_HAL_ANALOGIO_ANALOGOUT_H
|
@ -1 +0,0 @@
|
||||
// No analogio module functions.
|
@ -1,34 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "py/runtime.h"
|
||||
#include "py/mphal.h"
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
|
||||
// Pins aren't actually defined here. They are in the board specific directory
|
||||
// such as boards/feather_huzzah/pins.c.
|
@ -1,33 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Scott Shawcroft
|
||||
*
|
||||
* 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_ESP8266_COMMON_HAL_BUSIO_I2C_H
|
||||
#define MICROPY_INCLUDED_ESP8266_COMMON_HAL_BUSIO_I2C_H
|
||||
|
||||
// Use the bitbang wrapper for I2C
|
||||
#include "shared-module/busio/I2C.h"
|
||||
|
||||
#endif // MICROPY_INCLUDED_ESP8266_COMMON_HAL_BUSIO_I2C_H
|
@ -1,33 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Scott Shawcroft
|
||||
*
|
||||
* 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_ESP8266_COMMON_HAL_BUSIO_ONEWIRE_H
|
||||
#define MICROPY_INCLUDED_ESP8266_COMMON_HAL_BUSIO_ONEWIRE_H
|
||||
|
||||
// Use the bitbang wrapper for OneWire
|
||||
#include "shared-module/busio/OneWire.h"
|
||||
|
||||
#endif // MICROPY_INCLUDED_ESP8266_COMMON_HAL_BUSIO_ONEWIRE_H
|
@ -1,225 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Scott Shawcroft
|
||||
*
|
||||
* 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 "shared-bindings/microcontroller/__init__.h"
|
||||
#include "common-hal/busio/SPI.h"
|
||||
#include "py/nlr.h"
|
||||
#include "supervisor/shared/translate.h"
|
||||
|
||||
#include "eagle_soc.h"
|
||||
#include "ets_alt_task.h"
|
||||
#include "c_types.h"
|
||||
#include "gpio.h"
|
||||
#include "hspi.h"
|
||||
|
||||
extern const mcu_pin_obj_t pin_MTMS;
|
||||
extern const mcu_pin_obj_t pin_MTCK;
|
||||
extern const mcu_pin_obj_t pin_MTDI;
|
||||
|
||||
void busio_spi_init_gpio(uint8_t sysclk_as_spiclk, const mcu_pin_obj_t * clock,
|
||||
const mcu_pin_obj_t * mosi, const mcu_pin_obj_t * miso) {
|
||||
|
||||
uint32_t clock_div_flag = 0;
|
||||
if (sysclk_as_spiclk) {
|
||||
clock_div_flag = 0x0001;
|
||||
}
|
||||
|
||||
// Set bit 9 if 80MHz sysclock required
|
||||
WRITE_PERI_REG(PERIPHS_IO_MUX, 0x105 | (clock_div_flag<<9));
|
||||
// GPIO12 is HSPI MISO pin (Master Data In)
|
||||
if (miso == &pin_MTDI) {
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, 2);
|
||||
}
|
||||
// GPIO13 is HSPI MOSI pin (Master Data Out)
|
||||
if (mosi == &pin_MTCK) {
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 2);
|
||||
}
|
||||
// GPIO14 is HSPI CLK pin (Clock)
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 2);
|
||||
}
|
||||
|
||||
|
||||
void common_hal_busio_spi_construct(busio_spi_obj_t *self,
|
||||
const mcu_pin_obj_t * clock, const mcu_pin_obj_t * mosi,
|
||||
const mcu_pin_obj_t * miso) {
|
||||
if (clock != &pin_MTMS || !((mosi == &pin_MTCK && miso == MP_OBJ_TO_PTR(mp_const_none)) ||
|
||||
(mosi == MP_OBJ_TO_PTR(mp_const_none) && miso == &pin_MTDI) ||
|
||||
(mosi == &pin_MTCK && miso == &pin_MTDI))) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
|
||||
translate("Pins not valid for SPI")));
|
||||
}
|
||||
|
||||
busio_spi_init_gpio(SPI_CLK_USE_DIV, clock, mosi, miso);
|
||||
self->clock = clock;
|
||||
self->mosi = mosi;
|
||||
self->miso = miso;
|
||||
|
||||
spi_clock(HSPI, SPI_CLK_PREDIV, SPI_CLK_CNTDIV);
|
||||
self->frequency = SPI_CLK_FREQ;
|
||||
spi_tx_byte_order(HSPI, SPI_BYTE_ORDER_HIGH_TO_LOW);
|
||||
spi_rx_byte_order(HSPI, SPI_BYTE_ORDER_HIGH_TO_LOW);
|
||||
|
||||
SET_PERI_REG_MASK(SPI_USER(HSPI), SPI_CS_SETUP|SPI_CS_HOLD);
|
||||
CLEAR_PERI_REG_MASK(SPI_USER(HSPI), SPI_FLASH_MODE);
|
||||
}
|
||||
|
||||
bool common_hal_busio_spi_deinited(busio_spi_obj_t *self) {
|
||||
return self->deinited;
|
||||
}
|
||||
|
||||
void common_hal_busio_spi_deinit(busio_spi_obj_t *self) {
|
||||
if (common_hal_busio_spi_deinited(self)) {
|
||||
return;
|
||||
}
|
||||
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, 0);
|
||||
PIN_PULLUP_DIS(PERIPHS_IO_MUX_MTDI_U);
|
||||
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 0);
|
||||
PIN_PULLUP_DIS(PERIPHS_IO_MUX_MTCK_U);
|
||||
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 0);
|
||||
PIN_PULLUP_DIS(PERIPHS_IO_MUX_MTMS_U);
|
||||
|
||||
// Turn off outputs 12 - 14.
|
||||
gpio_output_set(0x0, 0x0, 0x0, 0x7 << 12);
|
||||
|
||||
self->deinited = true;
|
||||
}
|
||||
|
||||
bool common_hal_busio_spi_configure(busio_spi_obj_t *self,
|
||||
uint32_t baudrate, uint8_t polarity, uint8_t phase, uint8_t bits) {
|
||||
if (bits != 8) {
|
||||
return false;
|
||||
}
|
||||
if (baudrate == 80000000L) {
|
||||
// Special case for full speed.
|
||||
busio_spi_init_gpio(SPI_CLK_80MHZ_NODIV, self->clock, self->mosi, self->miso);
|
||||
spi_clock(HSPI, 0, 0);
|
||||
self->frequency = 80000000L;
|
||||
} else if (baudrate > 40000000L) {
|
||||
return false;
|
||||
} else {
|
||||
uint32_t divider = 40000000L / baudrate;
|
||||
uint16_t prediv = MIN(divider, SPI_CLKDIV_PRE + 1);
|
||||
uint16_t cntdiv = (divider / prediv) * 2; // cntdiv has to be even
|
||||
if (cntdiv > SPI_CLKCNT_N + 1 || cntdiv == 0 || prediv == 0) {
|
||||
return false;
|
||||
}
|
||||
busio_spi_init_gpio(SPI_CLK_USE_DIV, self->clock, self->mosi, self->miso);
|
||||
spi_clock(HSPI, prediv, cntdiv);
|
||||
self->frequency = 80000000L / (prediv * cntdiv);
|
||||
}
|
||||
spi_mode(HSPI, phase, polarity);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool common_hal_busio_spi_try_lock(busio_spi_obj_t *self) {
|
||||
bool success = false;
|
||||
common_hal_mcu_disable_interrupts();
|
||||
if (!self->locked) {
|
||||
self->locked = true;
|
||||
success = true;
|
||||
}
|
||||
common_hal_mcu_enable_interrupts();
|
||||
return success;
|
||||
}
|
||||
|
||||
bool common_hal_busio_spi_has_lock(busio_spi_obj_t *self) {
|
||||
return self->locked;
|
||||
}
|
||||
|
||||
void common_hal_busio_spi_unlock(busio_spi_obj_t *self) {
|
||||
self->locked = false;
|
||||
}
|
||||
|
||||
bool common_hal_busio_spi_write(busio_spi_obj_t *self,
|
||||
const uint8_t * data, size_t len) {
|
||||
size_t chunk_size = 1024;
|
||||
size_t count = len / chunk_size;
|
||||
size_t i = 0;
|
||||
for (size_t j = 0; j < count; ++j) {
|
||||
for (size_t k = 0; k < chunk_size; ++k) {
|
||||
spi_tx8fast(HSPI, data[i]);
|
||||
++i;
|
||||
}
|
||||
ets_loop_iter();
|
||||
}
|
||||
while (i < len) {
|
||||
spi_tx8fast(HSPI, data[i]);
|
||||
++i;
|
||||
}
|
||||
while (spi_busy(HSPI)) {}; // Wait for SPI to finish the last byte.
|
||||
return true;
|
||||
}
|
||||
|
||||
bool common_hal_busio_spi_read(busio_spi_obj_t *self,
|
||||
uint8_t * data, size_t len, uint8_t write_value) {
|
||||
// Process data in chunks, let the pending tasks run in between
|
||||
size_t chunk_size = 1024; // TODO this should depend on baudrate
|
||||
size_t count = len / chunk_size;
|
||||
size_t i = 0;
|
||||
uint32_t long_write_value = ((uint32_t) write_value) << 24 |
|
||||
write_value << 16 |
|
||||
write_value << 8 |
|
||||
write_value;
|
||||
for (size_t j = 0; j < count; ++j) {
|
||||
for (size_t k = 0; k < chunk_size; ++k) {
|
||||
data[i] = spi_transaction(HSPI, 0, 0, 0, 0, 8, long_write_value, 8, 0);
|
||||
++i;
|
||||
}
|
||||
ets_loop_iter();
|
||||
}
|
||||
while (i < len) {
|
||||
data[i] = spi_transaction(HSPI, 0, 0, 0, 0, 8, long_write_value, 8, 0);
|
||||
++i;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool common_hal_busio_spi_transfer(busio_spi_obj_t *self, uint8_t *data_out, uint8_t *data_in, size_t len) {
|
||||
// Process data in chunks, let the pending tasks run in between
|
||||
size_t chunk_size = 1024; // TODO this should depend on baudrate
|
||||
size_t count = len / chunk_size;
|
||||
size_t i = 0;
|
||||
for (size_t j = 0; j < count; ++j) {
|
||||
for (size_t k = 0; k < chunk_size; ++k) {
|
||||
data_in[i] = spi_transaction(HSPI, 0, 0, 0, 0, 8, data_out[i], 8, 0);
|
||||
++i;
|
||||
}
|
||||
ets_loop_iter();
|
||||
}
|
||||
while (i < len) {
|
||||
data_in[i] = spi_transaction(HSPI, 0, 0, 0, 0, 8, data_out[i], 8, 0);
|
||||
++i;
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
uint32_t common_hal_busio_spi_get_frequency(busio_spi_obj_t* self) {
|
||||
return self->frequency;
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Scott Shawcroft
|
||||
*
|
||||
* 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_ESP8266_COMMON_HAL_BUSIO_SPI_H
|
||||
#define MICROPY_INCLUDED_ESP8266_COMMON_HAL_BUSIO_SPI_H
|
||||
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
uint32_t frequency;
|
||||
bool locked;
|
||||
bool deinited;
|
||||
const mcu_pin_obj_t * mosi;
|
||||
const mcu_pin_obj_t * miso;
|
||||
const mcu_pin_obj_t * clock;
|
||||
} busio_spi_obj_t;
|
||||
|
||||
#endif // MICROPY_INCLUDED_ESP8266_COMMON_HAL_BUSIO_SPI_H
|
@ -1,146 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 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 "common-hal/microcontroller/__init__.h"
|
||||
#include "shared-bindings/microcontroller/__init__.h"
|
||||
#include "shared-bindings/busio/UART.h"
|
||||
#include "supervisor/shared/translate.h"
|
||||
|
||||
#include "ets_sys.h"
|
||||
#include "uart.h"
|
||||
|
||||
#include "py/nlr.h"
|
||||
|
||||
// UartDev is defined and initialized in rom code.
|
||||
extern UartDevice UartDev;
|
||||
|
||||
void common_hal_busio_uart_construct(busio_uart_obj_t *self,
|
||||
const mcu_pin_obj_t * tx, const mcu_pin_obj_t * rx, uint32_t baudrate,
|
||||
uint8_t bits, uart_parity_t parity, uint8_t stop, mp_float_t timeout,
|
||||
uint16_t receiver_buffer_size) {
|
||||
if (rx != mp_const_none || tx != &pin_GPIO2) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, translate("Only tx supported on UART1 (GPIO2).")));
|
||||
}
|
||||
|
||||
// set baudrate
|
||||
UartDev.baut_rate = baudrate;
|
||||
self->baudrate = baudrate;
|
||||
|
||||
// set data bits
|
||||
switch (bits) {
|
||||
case 5:
|
||||
UartDev.data_bits = UART_FIVE_BITS;
|
||||
break;
|
||||
case 6:
|
||||
UartDev.data_bits = UART_SIX_BITS;
|
||||
break;
|
||||
case 7:
|
||||
UartDev.data_bits = UART_SEVEN_BITS;
|
||||
break;
|
||||
case 8:
|
||||
UartDev.data_bits = UART_EIGHT_BITS;
|
||||
break;
|
||||
default:
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, translate("invalid data bits")));
|
||||
break;
|
||||
}
|
||||
|
||||
if (parity == PARITY_NONE) {
|
||||
UartDev.parity = UART_NONE_BITS;
|
||||
UartDev.exist_parity = UART_STICK_PARITY_DIS;
|
||||
} else {
|
||||
UartDev.exist_parity = UART_STICK_PARITY_EN;
|
||||
if (parity == PARITY_ODD) {
|
||||
UartDev.parity = UART_ODD_BITS;
|
||||
} else {
|
||||
UartDev.parity = UART_EVEN_BITS;
|
||||
}
|
||||
}
|
||||
|
||||
switch (stop) {
|
||||
case 1:
|
||||
UartDev.stop_bits = UART_ONE_STOP_BIT;
|
||||
break;
|
||||
case 2:
|
||||
UartDev.stop_bits = UART_TWO_STOP_BIT;
|
||||
break;
|
||||
default:
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, translate("invalid stop bits")));
|
||||
break;
|
||||
}
|
||||
|
||||
uart_setup(UART1);
|
||||
self->deinited = false;
|
||||
}
|
||||
|
||||
bool common_hal_busio_uart_deinited(busio_uart_obj_t *self) {
|
||||
return self->deinited;
|
||||
}
|
||||
|
||||
void common_hal_busio_uart_deinit(busio_uart_obj_t *self) {
|
||||
if (common_hal_busio_uart_deinited(self)) {
|
||||
return;
|
||||
}
|
||||
// Switch GPIO2 back to a GPIO pin.
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_GPIO2);
|
||||
self->deinited = true;
|
||||
}
|
||||
|
||||
size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t len, int *errcode) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Write characters.
|
||||
size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, size_t len, int *errcode) {
|
||||
// write the data
|
||||
for (size_t i = 0; i < len; ++i) {
|
||||
uart_tx_one_char(UART1, *data++);
|
||||
}
|
||||
|
||||
// return number of bytes written
|
||||
return len;
|
||||
}
|
||||
|
||||
uint32_t common_hal_busio_uart_get_baudrate(busio_uart_obj_t *self) {
|
||||
return self->baudrate;
|
||||
}
|
||||
|
||||
void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrate) {
|
||||
UartDev.baut_rate = baudrate;
|
||||
uart_setup(UART1);
|
||||
self->baudrate = baudrate;
|
||||
}
|
||||
|
||||
uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) {
|
||||
}
|
||||
|
||||
bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) {
|
||||
return true;
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Scott Shawcroft
|
||||
*
|
||||
* 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_ESP8266_COMMON_HAL_BUSIO_UART_H
|
||||
#define MICROPY_INCLUDED_ESP8266_COMMON_HAL_BUSIO_UART_H
|
||||
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
uint32_t baudrate;
|
||||
bool deinited;
|
||||
} busio_uart_obj_t;
|
||||
|
||||
#endif // MICROPY_INCLUDED_ESP8266_COMMON_HAL_BUSIO_UART_H
|
@ -1 +0,0 @@
|
||||
// No busio module functions.
|
@ -1,228 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 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 <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/nlr.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/mphal.h"
|
||||
|
||||
#include "shared-bindings/digitalio/DigitalInOut.h"
|
||||
#include "supervisor/shared/translate.h"
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
|
||||
extern volatile bool gpio16_in_use;
|
||||
|
||||
digitalinout_result_t common_hal_digitalio_digitalinout_construct(
|
||||
digitalio_digitalinout_obj_t* self, const mcu_pin_obj_t* pin) {
|
||||
self->pin = pin;
|
||||
if (self->pin->gpio_number == 16) {
|
||||
WRITE_PERI_REG(PAD_XPD_DCDC_CONF, (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | 1); // mux configuration for XPD_DCDC and rtc_gpio0 connection
|
||||
WRITE_PERI_REG(RTC_GPIO_CONF, READ_PERI_REG(RTC_GPIO_CONF) & ~1); //mux configuration for out enable
|
||||
WRITE_PERI_REG(RTC_GPIO_ENABLE, READ_PERI_REG(RTC_GPIO_ENABLE) & ~1); //out disable
|
||||
claim_pin(pin);
|
||||
} else {
|
||||
PIN_FUNC_SELECT(self->pin->peripheral, self->pin->gpio_function);
|
||||
}
|
||||
return DIGITALINOUT_OK;
|
||||
}
|
||||
|
||||
bool common_hal_digitalio_digitalinout_deinited(digitalio_digitalinout_obj_t* self) {
|
||||
return self->pin == mp_const_none;
|
||||
}
|
||||
|
||||
void common_hal_digitalio_digitalinout_deinit(digitalio_digitalinout_obj_t* self) {
|
||||
if (common_hal_digitalio_digitalinout_deinited(self)) {
|
||||
return;
|
||||
}
|
||||
if (self->pin->gpio_number < 16) {
|
||||
uint32_t pin_mask = 1 << self->pin->gpio_number;
|
||||
gpio_output_set(0x0, 0x0, 0x0, pin_mask);
|
||||
PIN_FUNC_SELECT(self->pin->peripheral, 0);
|
||||
PIN_PULLUP_DIS(self->pin->peripheral);
|
||||
} else {
|
||||
reset_pin(self->pin);
|
||||
}
|
||||
self->pin = mp_const_none;
|
||||
}
|
||||
|
||||
void common_hal_digitalio_digitalinout_switch_to_input(
|
||||
digitalio_digitalinout_obj_t* self, digitalio_pull_t pull) {
|
||||
self->output = false;
|
||||
|
||||
if (self->pin->gpio_number == 16) {
|
||||
WRITE_PERI_REG(PAD_XPD_DCDC_CONF, (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | 1);
|
||||
WRITE_PERI_REG(RTC_GPIO_CONF, READ_PERI_REG(RTC_GPIO_CONF) & ~1);
|
||||
WRITE_PERI_REG(RTC_GPIO_ENABLE, (READ_PERI_REG(RTC_GPIO_ENABLE) & ~1)); // input
|
||||
} else {
|
||||
PIN_PULLUP_DIS(self->pin->peripheral);
|
||||
gpio_output_set(0, 0, 0, 1 << self->pin->gpio_number);
|
||||
}
|
||||
common_hal_digitalio_digitalinout_set_pull(self, pull);
|
||||
}
|
||||
|
||||
void common_hal_digitalio_digitalinout_switch_to_output(
|
||||
digitalio_digitalinout_obj_t* self, bool value,
|
||||
digitalio_drive_mode_t drive_mode) {
|
||||
self->output = true;
|
||||
self->open_drain = drive_mode == DRIVE_MODE_OPEN_DRAIN;
|
||||
if (self->pin->gpio_number == 16) {
|
||||
WRITE_PERI_REG(PAD_XPD_DCDC_CONF, (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | 1);
|
||||
WRITE_PERI_REG(RTC_GPIO_CONF, READ_PERI_REG(RTC_GPIO_CONF) & ~1);
|
||||
WRITE_PERI_REG(RTC_GPIO_ENABLE, (READ_PERI_REG(RTC_GPIO_ENABLE) & ~1) | 1); // output
|
||||
} else if (!self->open_drain) {
|
||||
gpio_output_set(0, 0, 1 << self->pin->gpio_number, 0);
|
||||
PIN_PULLUP_DIS(self->pin->peripheral);
|
||||
}
|
||||
common_hal_digitalio_digitalinout_set_value(self, value);
|
||||
}
|
||||
|
||||
digitalio_direction_t common_hal_digitalio_digitalinout_get_direction(
|
||||
digitalio_digitalinout_obj_t* self) {
|
||||
return self->output? DIRECTION_OUTPUT : DIRECTION_INPUT;
|
||||
}
|
||||
|
||||
void common_hal_digitalio_digitalinout_set_value(
|
||||
digitalio_digitalinout_obj_t* self, bool value) {
|
||||
if (self->pin->gpio_number == 16) {
|
||||
if (self->open_drain && value) {
|
||||
// configure GPIO16 as input with output register holding 0
|
||||
WRITE_PERI_REG(PAD_XPD_DCDC_CONF, (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | 1);
|
||||
WRITE_PERI_REG(RTC_GPIO_CONF, READ_PERI_REG(RTC_GPIO_CONF) & ~1);
|
||||
WRITE_PERI_REG(RTC_GPIO_ENABLE, (READ_PERI_REG(RTC_GPIO_ENABLE) & ~1)); // input
|
||||
WRITE_PERI_REG(RTC_GPIO_OUT, (READ_PERI_REG(RTC_GPIO_OUT) & 1)); // out=1
|
||||
return;
|
||||
} else {
|
||||
int out_en = self->output;
|
||||
WRITE_PERI_REG(PAD_XPD_DCDC_CONF, (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | 1);
|
||||
WRITE_PERI_REG(RTC_GPIO_CONF, READ_PERI_REG(RTC_GPIO_CONF) & ~1);
|
||||
WRITE_PERI_REG(RTC_GPIO_ENABLE, (READ_PERI_REG(RTC_GPIO_ENABLE) & ~1) | out_en);
|
||||
WRITE_PERI_REG(RTC_GPIO_OUT, (READ_PERI_REG(RTC_GPIO_OUT) & ~1) | value);
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (value) {
|
||||
if (self->open_drain) {
|
||||
// Disable output.
|
||||
gpio_output_set(0, 0, 0, 1 << self->pin->gpio_number);
|
||||
} else {
|
||||
// Set high
|
||||
gpio_output_set(1 << self->pin->gpio_number, 0, 0, 0);
|
||||
}
|
||||
} else {
|
||||
if (self->open_drain) {
|
||||
// Enable the output
|
||||
gpio_output_set(0, 0, 1 << self->pin->gpio_number, 0);
|
||||
}
|
||||
// Set low
|
||||
gpio_output_set(0, 1 << self->pin->gpio_number, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
// Register addresses taken from: https://github.com/esp8266/esp8266-wiki/wiki/gpio-registers
|
||||
volatile uint32_t* PIN_DIR = (uint32_t *) 0x6000030C;
|
||||
volatile uint32_t* PIN_OUT = (uint32_t *) 0x60000300;
|
||||
bool common_hal_digitalio_digitalinout_get_value(
|
||||
digitalio_digitalinout_obj_t* self) {
|
||||
if (!self->output) {
|
||||
if (self->pin->gpio_number == 16) {
|
||||
return READ_PERI_REG(RTC_GPIO_IN_DATA) & 1;
|
||||
}
|
||||
return GPIO_INPUT_GET(self->pin->gpio_number);
|
||||
} else {
|
||||
if (self->pin->gpio_number == 16) {
|
||||
if (self->open_drain && READ_PERI_REG(RTC_GPIO_ENABLE) == 0) {
|
||||
return true;
|
||||
} else {
|
||||
return READ_PERI_REG(RTC_GPIO_OUT) & 1;
|
||||
}
|
||||
} else {
|
||||
uint32_t pin_mask = 1 << self->pin->gpio_number;
|
||||
if (self->open_drain && ((*PIN_DIR) & pin_mask) == 0) {
|
||||
return true;
|
||||
} else {
|
||||
return ((*PIN_OUT) & pin_mask) != 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void common_hal_digitalio_digitalinout_set_drive_mode(
|
||||
digitalio_digitalinout_obj_t* self,
|
||||
digitalio_drive_mode_t drive_mode) {
|
||||
bool value = common_hal_digitalio_digitalinout_get_value(self);
|
||||
self->open_drain = drive_mode == DRIVE_MODE_OPEN_DRAIN;
|
||||
// True is implemented differently between modes so reset the value to make
|
||||
// sure its correct for the new mode.
|
||||
if (value) {
|
||||
common_hal_digitalio_digitalinout_set_value(self, value);
|
||||
}
|
||||
}
|
||||
|
||||
digitalio_drive_mode_t common_hal_digitalio_digitalinout_get_drive_mode(
|
||||
digitalio_digitalinout_obj_t* self) {
|
||||
if (self->open_drain) {
|
||||
return DRIVE_MODE_OPEN_DRAIN;
|
||||
} else {
|
||||
return DRIVE_MODE_PUSH_PULL;
|
||||
}
|
||||
}
|
||||
|
||||
void common_hal_digitalio_digitalinout_set_pull(
|
||||
digitalio_digitalinout_obj_t* self, digitalio_pull_t pull) {
|
||||
if (pull == PULL_DOWN) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError,
|
||||
translate("ESP8266 does not support pull down.")));
|
||||
return;
|
||||
}
|
||||
if (self->pin->gpio_number == 16) {
|
||||
// PULL_DOWN is the only hardware pull direction available on GPIO16.
|
||||
// since we don't support pull down, just return without attempting
|
||||
// to set pull (which won't work anyway). If PULL_UP is requested,
|
||||
// raise the exception so the user knows PULL_UP is not available
|
||||
if (pull != PULL_NONE){
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError,
|
||||
translate("GPIO16 does not support pull up.")));
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (pull == PULL_NONE) {
|
||||
PIN_PULLUP_DIS(self->pin->peripheral);
|
||||
} else {
|
||||
PIN_PULLUP_EN(self->pin->peripheral);
|
||||
}
|
||||
}
|
||||
|
||||
digitalio_pull_t common_hal_digitalio_digitalinout_get_pull(
|
||||
digitalio_digitalinout_obj_t* self) {
|
||||
if (self->pin->gpio_number < 16 &&
|
||||
(READ_PERI_REG(self->pin->peripheral) & PERIPHS_IO_MUX_PULLUP) != 0) {
|
||||
return PULL_UP;
|
||||
}
|
||||
return PULL_NONE;
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* 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_ESP8266_COMMON_HAL_DIGITALIO_DIGITALINOUT_H
|
||||
#define MICROPY_INCLUDED_ESP8266_COMMON_HAL_DIGITALIO_DIGITALINOUT_H
|
||||
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
#include "py/obj.h"
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
const mcu_pin_obj_t * pin;
|
||||
bool output;
|
||||
bool open_drain;
|
||||
} digitalio_digitalinout_obj_t;
|
||||
|
||||
#endif // MICROPY_INCLUDED_ESP8266_COMMON_HAL_DIGITALIO_DIGITALINOUT_H
|
@ -1 +0,0 @@
|
||||
// No digitalio module functions.
|
@ -1,118 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* 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 "shared-bindings/microcontroller/__init__.h"
|
||||
#include "common-hal/microcontroller/__init__.h"
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
#include "shared-bindings/microcontroller/Pin.h"
|
||||
|
||||
#include "py/mphal.h"
|
||||
|
||||
#include "eagle_soc.h"
|
||||
|
||||
bool adc_in_use;
|
||||
bool gpio16_in_use;
|
||||
|
||||
typedef struct {
|
||||
void (*func)(void *);
|
||||
void *data;
|
||||
} pin_intr_handler_t;
|
||||
|
||||
static pin_intr_handler_t _pin_intr_handlers[GPIO_PIN_COUNT];
|
||||
|
||||
void microcontroller_pin_call_intr_handlers(uint32_t status) {
|
||||
status &= (1 << GPIO_PIN_COUNT) - 1;
|
||||
for (int p = 0; status; ++p, status >>= 1) {
|
||||
if ((status & 1) && _pin_intr_handlers[p].func) {
|
||||
_pin_intr_handlers[p].func(_pin_intr_handlers[p].data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void microcontroller_pin_register_intr_handler(uint8_t gpio_number, void (*func)(void *), void *data) {
|
||||
common_hal_mcu_disable_interrupts();
|
||||
_pin_intr_handlers[gpio_number] = (pin_intr_handler_t){ func, data };
|
||||
common_hal_mcu_enable_interrupts();
|
||||
}
|
||||
|
||||
bool common_hal_mcu_pin_is_free(const mcu_pin_obj_t* pin) {
|
||||
if (pin == &pin_TOUT) {
|
||||
return !adc_in_use;
|
||||
}
|
||||
if (pin == &pin_XPD_DCDC) {
|
||||
return !gpio16_in_use;
|
||||
}
|
||||
if (pin->gpio_number == NO_GPIO) {
|
||||
return false;
|
||||
}
|
||||
return (READ_PERI_REG(pin->peripheral) &
|
||||
(PERIPHS_IO_MUX_FUNC<<PERIPHS_IO_MUX_FUNC_S)) == 0 &&
|
||||
(GPIO_REG_READ(GPIO_ENABLE_ADDRESS) & (1 << pin->gpio_number)) == 0 &&
|
||||
(READ_PERI_REG(pin->peripheral) & PERIPHS_IO_MUX_PULLUP) == 0;
|
||||
}
|
||||
|
||||
void claim_pin(const mcu_pin_obj_t* pin) {
|
||||
if (pin == &pin_XPD_DCDC) {
|
||||
gpio16_in_use = true;
|
||||
}
|
||||
if (pin == &pin_TOUT) {
|
||||
adc_in_use = true;
|
||||
}
|
||||
}
|
||||
|
||||
void reset_pin(const mcu_pin_obj_t* pin) {
|
||||
if (pin == &pin_XPD_DCDC) {
|
||||
// Set GPIO16 as input
|
||||
WRITE_PERI_REG(PAD_XPD_DCDC_CONF, (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | 1); // mux configuration for XPD_DCDC and rtc_gpio0 connection
|
||||
WRITE_PERI_REG(RTC_GPIO_CONF, READ_PERI_REG(RTC_GPIO_CONF) & ~1); //mux configuration for out enable
|
||||
WRITE_PERI_REG(RTC_GPIO_ENABLE, READ_PERI_REG(RTC_GPIO_ENABLE) & ~1); //out disable
|
||||
gpio16_in_use = false;
|
||||
}
|
||||
if (pin == &pin_TOUT) {
|
||||
adc_in_use = false;
|
||||
}
|
||||
}
|
||||
|
||||
void reset_pins(void) {
|
||||
for (int i = 0; i < 16; i++) {
|
||||
// 5 is RXD, 6 is TXD
|
||||
if ((i > 4 && i < 13) || i == 12) {
|
||||
continue;
|
||||
}
|
||||
uint32_t peripheral = PERIPHS_IO_MUX + i * 4;
|
||||
PIN_FUNC_SELECT(peripheral, 0);
|
||||
PIN_PULLUP_DIS(peripheral);
|
||||
// Disable the pin.
|
||||
gpio_output_set(0x0, 0x0, 0x0, 1 << i);
|
||||
}
|
||||
// Set GPIO16 as input
|
||||
WRITE_PERI_REG(PAD_XPD_DCDC_CONF, (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | 1); // mux configuration for XPD_DCDC and rtc_gpio0 connection
|
||||
WRITE_PERI_REG(RTC_GPIO_CONF, READ_PERI_REG(RTC_GPIO_CONF) & ~1); //mux configuration for out enable
|
||||
WRITE_PERI_REG(RTC_GPIO_ENABLE, READ_PERI_REG(RTC_GPIO_ENABLE) & ~1); //out disable
|
||||
|
||||
adc_in_use = false;
|
||||
gpio16_in_use = false;
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* 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_ESP8266_COMMON_HAL_MICROCONTROLLER_PIN_H
|
||||
#define MICROPY_INCLUDED_ESP8266_COMMON_HAL_MICROCONTROLLER_PIN_H
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
qstr name;
|
||||
uint8_t gpio_number;
|
||||
uint8_t gpio_function;
|
||||
uint32_t peripheral;
|
||||
} mcu_pin_obj_t;
|
||||
|
||||
// Magic values for gpio_number.
|
||||
#define NO_GPIO 0xff
|
||||
#define SPECIAL_CASE 0xfe
|
||||
|
||||
void claim_pin(const mcu_pin_obj_t* pin);
|
||||
void reset_pin(const mcu_pin_obj_t* pin);
|
||||
void reset_pins(void);
|
||||
|
||||
void microcontroller_pin_register_intr_handler(uint8_t gpio_number, void (*func)(void *), void *data);
|
||||
void microcontroller_pin_call_intr_handlers(uint32_t status);
|
||||
|
||||
#endif // MICROPY_INCLUDED_ESP8266_COMMON_HAL_MICROCONTROLLER_PIN_H
|
@ -1,48 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 Dan Halbert for Adafruit Industries
|
||||
*
|
||||
* 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 "common-hal/microcontroller/Processor.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "esp_mphal.h"
|
||||
#include "user_interface.h"
|
||||
|
||||
|
||||
float common_hal_mcu_processor_get_temperature(void) {
|
||||
return NAN;
|
||||
}
|
||||
|
||||
uint32_t common_hal_mcu_processor_get_frequency(void) {
|
||||
return mp_hal_get_cpu_freq();
|
||||
}
|
||||
|
||||
void common_hal_mcu_processor_get_uid(uint8_t raw_id[]) {
|
||||
uint32_t id = system_get_chip_id();
|
||||
for (int i=0; i<4; i++){
|
||||
raw_id[i] = id >> (i * 8);
|
||||
}
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 Dan Halbert for Adafruit Industries
|
||||
*
|
||||
* 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_ESP8266_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H
|
||||
#define MICROPY_INCLUDED_ESP8266_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H
|
||||
|
||||
#define COMMON_HAL_MCU_PROCESSOR_UID_LENGTH 4
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
// Stores no state currently.
|
||||
} mcu_processor_obj_t;
|
||||
|
||||
#endif // MICROPY_INCLUDED_ESP8266_COMMON_HAL_MICROCONTROLLER_PROCESSOR_H
|
@ -1,135 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* 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 "py/runtime.h"
|
||||
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
#include "common-hal/microcontroller/Processor.h"
|
||||
|
||||
#include "shared-bindings/microcontroller/__init__.h"
|
||||
#include "shared-bindings/microcontroller/Pin.h"
|
||||
#include "shared-bindings/microcontroller/Processor.h"
|
||||
#include "supervisor/shared/translate.h"
|
||||
|
||||
#include "eagle_soc.h"
|
||||
#include "ets_alt_task.h"
|
||||
#include "etshal.h"
|
||||
#include "osapi.h"
|
||||
#include "user_interface.h"
|
||||
#include "xtirq.h"
|
||||
|
||||
#define ETS_LOOP_ITER_BIT (12)
|
||||
|
||||
void common_hal_mcu_delay_us(uint32_t delay) {
|
||||
os_delay_us(delay);
|
||||
}
|
||||
|
||||
static uint16_t saved_interrupt_state;
|
||||
void common_hal_mcu_disable_interrupts() {
|
||||
saved_interrupt_state = disable_irq();
|
||||
saved_interrupt_state = (saved_interrupt_state & ~(1 << ETS_LOOP_ITER_BIT)) | (ets_loop_iter_disable << ETS_LOOP_ITER_BIT);
|
||||
ets_loop_iter_disable = 1;
|
||||
}
|
||||
|
||||
void common_hal_mcu_enable_interrupts() {
|
||||
ets_loop_iter_disable = (saved_interrupt_state >> ETS_LOOP_ITER_BIT) & 1;
|
||||
enable_irq(saved_interrupt_state & ~(1 << ETS_LOOP_ITER_BIT));
|
||||
}
|
||||
|
||||
void common_hal_mcu_on_next_reset(mcu_runmode_t runmode) {
|
||||
if (runmode == RUNMODE_BOOTLOADER) {
|
||||
mp_raise_ValueError(translate("Cannot reset into bootloader because no bootloader is present."));
|
||||
} else if (runmode == RUNMODE_SAFE_MODE) {
|
||||
mp_raise_ValueError(translate("ESP8226 does not support safe mode."));
|
||||
}
|
||||
}
|
||||
|
||||
void common_hal_mcu_reset(void) {
|
||||
system_restart();
|
||||
}
|
||||
|
||||
// The singleton microcontroller.Processor object, returned by microcontroller.cpu
|
||||
// It currently only has properties, and no state.
|
||||
const mcu_processor_obj_t common_hal_mcu_processor_obj = {
|
||||
.base = {
|
||||
.type = &mcu_processor_type,
|
||||
},
|
||||
};
|
||||
|
||||
// This macro is used to simplify pin definition in boards/<board>/pins.c
|
||||
#define PIN(p_name, p_gpio_number, p_gpio_function, p_peripheral) \
|
||||
const mcu_pin_obj_t pin_## p_name = { \
|
||||
{ &mcu_pin_type }, \
|
||||
.name = MP_QSTR_ ## p_name, \
|
||||
.gpio_number = p_gpio_number, \
|
||||
.gpio_function = p_gpio_function, \
|
||||
.peripheral = p_peripheral, \
|
||||
}
|
||||
|
||||
// Using microcontroller names from the datasheet.
|
||||
// https://cdn-shop.adafruit.com/datasheets/ESP8266_Specifications_English.pdf
|
||||
// PIN(mcu name) // function notes | module name | huzzah name
|
||||
PIN(TOUT, NO_GPIO, NO_GPIO, NO_GPIO); // adc | ADC | ADC
|
||||
PIN(XPD_DCDC, 16, SPECIAL_CASE, SPECIAL_CASE); // gpio16 | GPIO16 | GPIO16
|
||||
PIN(MTMS, 14, FUNC_GPIO14, PERIPHS_IO_MUX_MTMS_U); // gpio14 / hspi_clk / pwm2 | GPIO14 | GPIO14/SCK
|
||||
PIN(MTDI, 12, FUNC_GPIO12, PERIPHS_IO_MUX_MTDI_U); // gpio12 / hspi_miso / pwm0 | GPIO12 | GPIO12/MISO
|
||||
PIN(MTCK, 13, FUNC_GPIO13, PERIPHS_IO_MUX_MTCK_U); // gpio13 / hspi_mosi / U0cts | GPIO13 | GPIO13/MOSI
|
||||
PIN(MTDO, 15, FUNC_GPIO15, PERIPHS_IO_MUX_MTDO_U); // gpio15 / hspi_cs / u0rts / pwm1 | GPIO15 | GPIO15
|
||||
PIN(GPIO2, 2, FUNC_GPIO2, PERIPHS_IO_MUX_GPIO2_U); // U1txd | GPIO2 | GPIO2
|
||||
PIN(GPIO0, 0, FUNC_GPIO0, PERIPHS_IO_MUX_GPIO0_U); // spi_Cs2 | GPIO0 | GPIO0
|
||||
PIN(GPIO4, 4, FUNC_GPIO4, PERIPHS_IO_MUX_GPIO4_U); // pwm3 on mcu datasheet as vdd which must be wrong | GPIO4 | GPIO4/SDA
|
||||
PIN(SD_DATA_2, 9, FUNC_GPIO9, PERIPHS_IO_MUX_SD_DATA2_U); // spihd / hspihd / gpio9 | GPIO9
|
||||
PIN(SD_DATA_3, 10, FUNC_GPIO10, PERIPHS_IO_MUX_SD_DATA3_U); // spiwp / hspiwp / gpio10 | GPIO10
|
||||
PIN(SD_CMD, NO_GPIO, NO_GPIO, PERIPHS_IO_MUX_SD_CMD_U); // spi_cs0 / gpio11 | CS0
|
||||
PIN(SD_CLK, NO_GPIO, NO_GPIO, PERIPHS_IO_MUX_SD_CLK_U); // spi_clk / gpio6 | SCLK
|
||||
PIN(SD_DATA_0, NO_GPIO, NO_GPIO, PERIPHS_IO_MUX_SD_DATA0_U); // spi_miso / gpio7 | MISO
|
||||
PIN(SD_DATA_1, NO_GPIO, NO_GPIO, PERIPHS_IO_MUX_SD_DATA1_U); // spi_mosi / gpio8 / u1rxd | MOSI
|
||||
PIN(DVDD, 5, FUNC_GPIO5, PERIPHS_IO_MUX_GPIO5_U); // gpio5 | GPIO5 | GPIO5/SCL
|
||||
PIN(U0RXD, 3, FUNC_GPIO3, PERIPHS_IO_MUX_U0RXD_U); // gpio3 | RXD0 | RXD
|
||||
PIN(U0TXD, 1, FUNC_GPIO1, PERIPHS_IO_MUX_U0TXD_U); // gpio1 / spi_cs1 | TXD0 | TXD
|
||||
|
||||
// This maps MCU pin names to pin objects.
|
||||
STATIC const mp_rom_map_elem_t mcu_pin_global_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_TOUT), MP_ROM_PTR(&pin_TOUT) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_XPD_DCDC), MP_ROM_PTR(&pin_XPD_DCDC) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_MTMS), MP_ROM_PTR(&pin_MTMS) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_MTDI), MP_ROM_PTR(&pin_MTDI) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_MTCK), MP_ROM_PTR(&pin_MTCK) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_MTDO), MP_ROM_PTR(&pin_MTDO) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_GPIO2), MP_ROM_PTR(&pin_GPIO2) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_GPIO0), MP_ROM_PTR(&pin_GPIO0) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_GPIO4), MP_ROM_PTR(&pin_GPIO4) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_SD_DATA_2), MP_ROM_PTR(&pin_SD_DATA_2) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_SD_DATA_3), MP_ROM_PTR(&pin_SD_DATA_3) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_SD_CMD), MP_ROM_PTR(&pin_SD_CMD) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_SD_CLK), MP_ROM_PTR(&pin_SD_CLK) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_SD_DATA_0), MP_ROM_PTR(&pin_SD_DATA_0) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_SD_DATA_1), MP_ROM_PTR(&pin_SD_DATA_1) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_DVDD), MP_ROM_PTR(&pin_DVDD) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_U0RXD), MP_ROM_PTR(&pin_U0RXD) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_U0TXD), MP_ROM_PTR(&pin_U0TXD) },
|
||||
};
|
||||
MP_DEFINE_CONST_DICT(mcu_pin_globals, mcu_pin_global_dict_table);
|
@ -1,51 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* 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_ESP8266_COMMON_HAL_MICROCONTROLLER___INIT___H
|
||||
#define MICROPY_INCLUDED_ESP8266_COMMON_HAL_MICROCONTROLLER___INIT___H
|
||||
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
|
||||
extern const mcu_pin_obj_t pin_TOUT;
|
||||
extern const mcu_pin_obj_t pin_XPD_DCDC;
|
||||
extern const mcu_pin_obj_t pin_MTMS;
|
||||
extern const mcu_pin_obj_t pin_MTDI;
|
||||
extern const mcu_pin_obj_t pin_MTCK;
|
||||
extern const mcu_pin_obj_t pin_MTDO;
|
||||
extern const mcu_pin_obj_t pin_GPIO2;
|
||||
extern const mcu_pin_obj_t pin_GPIO0;
|
||||
extern const mcu_pin_obj_t pin_GPIO4;
|
||||
extern const mcu_pin_obj_t pin_SD_DATA_2;
|
||||
extern const mcu_pin_obj_t pin_SD_DATA_3;
|
||||
extern const mcu_pin_obj_t pin_SD_CMD;
|
||||
extern const mcu_pin_obj_t pin_SD_CLK;
|
||||
extern const mcu_pin_obj_t pin_SD_DATA_0;
|
||||
extern const mcu_pin_obj_t pin_SD_DATA_1;
|
||||
extern const mcu_pin_obj_t pin_DVDD;
|
||||
extern const mcu_pin_obj_t pin_U0RXD;
|
||||
extern const mcu_pin_obj_t pin_U0TXD;
|
||||
|
||||
#endif // MICROPY_INCLUDED_ESP8266_COMMON_HAL_MICROCONTROLLER___INIT___H
|
@ -1,48 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Paul Sokolovsky
|
||||
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* 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 "esp_mphal.h"
|
||||
|
||||
#include "shared-bindings/multiterminal/__init__.h"
|
||||
#include "shared-module/multiterminal/__init__.h"
|
||||
|
||||
void common_hal_multiterminal_schedule_secondary_terminal_read(mp_obj_t socket) {
|
||||
(void) socket;
|
||||
mp_hal_signal_dupterm_input();
|
||||
}
|
||||
|
||||
mp_obj_t common_hal_multiterminal_get_secondary_terminal() {
|
||||
return shared_module_multiterminal_get_secondary_terminal();
|
||||
}
|
||||
|
||||
void common_hal_multiterminal_set_secondary_terminal(mp_obj_t secondary_terminal) {
|
||||
shared_module_multiterminal_set_secondary_terminal(secondary_terminal);
|
||||
}
|
||||
|
||||
void common_hal_multiterminal_clear_secondary_terminal() {
|
||||
shared_module_multiterminal_clear_secondary_terminal();
|
||||
}
|
@ -1,33 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* 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 "shared-bindings/neopixel_write/__init__.h"
|
||||
|
||||
#include "espneopixel.h"
|
||||
|
||||
void common_hal_neopixel_write(const digitalio_digitalinout_obj_t* digitalinout, uint8_t *pixels, uint32_t numBytes) {
|
||||
esp_neopixel_write(digitalinout->pin->gpio_number, pixels, numBytes, true /*800 kHz*/);
|
||||
}
|
@ -1,82 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Josef Gajdusek
|
||||
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* 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 "esp_mphal.h"
|
||||
#include "etshal.h"
|
||||
#include "py/objtuple.h"
|
||||
#include "py/objstr.h"
|
||||
#include "extmod/misc.h"
|
||||
#include "genhdr/mpversion.h"
|
||||
#include "user_interface.h"
|
||||
|
||||
STATIC const qstr os_uname_info_fields[] = {
|
||||
MP_QSTR_sysname, MP_QSTR_nodename,
|
||||
MP_QSTR_release, MP_QSTR_version, MP_QSTR_machine
|
||||
};
|
||||
STATIC const MP_DEFINE_STR_OBJ(os_uname_info_sysname_obj, MICROPY_PY_SYS_PLATFORM);
|
||||
STATIC const MP_DEFINE_STR_OBJ(os_uname_info_nodename_obj, MICROPY_PY_SYS_PLATFORM);
|
||||
STATIC const MP_DEFINE_STR_OBJ(os_uname_info_version_obj, MICROPY_GIT_TAG " on " MICROPY_BUILD_DATE);
|
||||
STATIC const MP_DEFINE_STR_OBJ(os_uname_info_machine_obj, MICROPY_HW_BOARD_NAME " with " MICROPY_HW_MCU_NAME);
|
||||
|
||||
STATIC mp_obj_tuple_t os_uname_info_obj = {
|
||||
.base = {&mp_type_attrtuple},
|
||||
.len = 5,
|
||||
.items = {
|
||||
(mp_obj_t)&os_uname_info_sysname_obj,
|
||||
(mp_obj_t)&os_uname_info_nodename_obj,
|
||||
NULL,
|
||||
(mp_obj_t)&os_uname_info_version_obj,
|
||||
(mp_obj_t)&os_uname_info_machine_obj,
|
||||
(void *)os_uname_info_fields,
|
||||
}
|
||||
};
|
||||
|
||||
mp_obj_t common_hal_os_uname(void) {
|
||||
// We must populate the "release" field each time in case it was GC'd since the last call.
|
||||
const char *ver = system_get_sdk_version();
|
||||
os_uname_info_obj.items[2] = mp_obj_new_str(ver, strlen(ver));
|
||||
return (mp_obj_t)&os_uname_info_obj;
|
||||
}
|
||||
|
||||
static uint32_t last_random;
|
||||
bool common_hal_os_urandom(uint8_t* buffer, uint32_t length) {
|
||||
uint32_t i = 0;
|
||||
while (i < length) {
|
||||
uint32_t new_random = last_random;
|
||||
while (new_random == last_random) {
|
||||
new_random = *WDEV_HWRNG;
|
||||
}
|
||||
for (int j = 0; j < 4 && i < length; j++) {
|
||||
buffer[i] = new_random & 0xff;
|
||||
i++;
|
||||
new_random >>= 8;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
@ -1,127 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 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 <stdint.h>
|
||||
|
||||
#include "esppwm.h"
|
||||
|
||||
#include "py/runtime.h"
|
||||
#include "shared-bindings/pulseio/PWMOut.h"
|
||||
#include "supervisor/shared/translate.h"
|
||||
|
||||
#include "eagle_soc.h"
|
||||
#include "c_types.h"
|
||||
#include "gpio.h"
|
||||
|
||||
#define PWM_FREQ_MAX 1000
|
||||
|
||||
// Shared with pybpwm
|
||||
extern bool pwm_inited;
|
||||
bool first_channel_variable;
|
||||
|
||||
void pwmout_reset(void) {
|
||||
first_channel_variable = false;
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pwmout_construct(pulseio_pwmout_obj_t* self, const mcu_pin_obj_t* pin, uint16_t duty, uint32_t frequency,
|
||||
bool variable_frequency) {
|
||||
if (frequency > PWM_FREQ_MAX) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
|
||||
translate("Maximum PWM frequency is %dhz."), PWM_FREQ_MAX));
|
||||
} else if (frequency < 1) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError,
|
||||
translate("Minimum PWM frequency is 1hz.")));
|
||||
}
|
||||
|
||||
// start the PWM subsystem if it's not already running
|
||||
if (!pwm_inited) {
|
||||
pwm_init();
|
||||
pwm_inited = true;
|
||||
pwm_set_freq(frequency, 0);
|
||||
first_channel_variable = variable_frequency;
|
||||
} else if (first_channel_variable || pwm_get_freq(0) != frequency) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
|
||||
translate("Multiple PWM frequencies not supported. PWM already set to %dhz."), pwm_get_freq(0)));
|
||||
}
|
||||
|
||||
self->channel = pwm_add(pin->gpio_number,
|
||||
pin->peripheral,
|
||||
pin->gpio_function);
|
||||
self->pin = pin;
|
||||
if (self->channel == -1) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
|
||||
translate("PWM not supported on pin %d"), pin->gpio_number));
|
||||
}
|
||||
}
|
||||
|
||||
bool common_hal_pulseio_pwmout_deinited(pulseio_pwmout_obj_t* self) {
|
||||
return self->pin == mp_const_none;
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pwmout_deinit(pulseio_pwmout_obj_t* self) {
|
||||
if (common_hal_pulseio_pwmout_deinited(self)) {
|
||||
return;
|
||||
}
|
||||
pwm_delete(self->channel);
|
||||
pwm_start();
|
||||
if (self->pin->gpio_number < 16) {
|
||||
uint32_t pin_mask = 1 << self->pin->gpio_number;
|
||||
gpio_output_set(0x0, 0x0, 0x0, pin_mask);
|
||||
PIN_FUNC_SELECT(self->pin->peripheral, 0);
|
||||
PIN_PULLUP_DIS(self->pin->peripheral);
|
||||
}
|
||||
self->pin = mp_const_none;
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pwmout_set_duty_cycle(pulseio_pwmout_obj_t* self, uint16_t duty) {
|
||||
// We get 16 bits of duty in but the underlying code is only ten bit.
|
||||
pwm_set_duty(duty >> 6, self->channel);
|
||||
pwm_start();
|
||||
}
|
||||
|
||||
uint16_t common_hal_pulseio_pwmout_get_duty_cycle(pulseio_pwmout_obj_t* self) {
|
||||
return pwm_get_duty(self->channel) << 6;
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pwmout_set_frequency(pulseio_pwmout_obj_t* self, uint32_t frequency) {
|
||||
if (frequency > PWM_FREQ_MAX) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_OSError,
|
||||
translate("Maximum PWM frequency is %dhz."), PWM_FREQ_MAX));
|
||||
} else if (frequency < 1) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError,
|
||||
translate("Minimum PWM frequency is 1hz.")));
|
||||
}
|
||||
pwm_set_freq(frequency, 0);
|
||||
}
|
||||
|
||||
uint32_t common_hal_pulseio_pwmout_get_frequency(pulseio_pwmout_obj_t* self) {
|
||||
return pwm_get_freq(0);
|
||||
}
|
||||
|
||||
bool common_hal_pulseio_pwmout_get_variable_frequency(pulseio_pwmout_obj_t* self) {
|
||||
return first_channel_variable;
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* 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_ESP8266_COMMON_HAL_PULSEIO_PWMOUT_H
|
||||
#define MICROPY_INCLUDED_ESP8266_COMMON_HAL_PULSEIO_PWMOUT_H
|
||||
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
int channel;
|
||||
const mcu_pin_obj_t* pin;
|
||||
} pulseio_pwmout_obj_t;
|
||||
|
||||
void pwmout_reset(void);
|
||||
|
||||
#endif // MICROPY_INCLUDED_ESP8266_COMMON_HAL_PULSEIO_PWMOUT_H
|
@ -1,187 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* 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>
|
||||
|
||||
#include <user_interface.h>
|
||||
#include <eagle_soc.h>
|
||||
#include "esp_mphal.h"
|
||||
|
||||
#include "mpconfigport.h"
|
||||
#include "py/gc.h"
|
||||
#include "py/runtime.h"
|
||||
#include "shared-bindings/microcontroller/__init__.h"
|
||||
#include "shared-bindings/pulseio/PulseIn.h"
|
||||
#include "supervisor/shared/translate.h"
|
||||
#include "common-hal/microcontroller/__init__.h"
|
||||
|
||||
static void pulsein_set_interrupt(pulseio_pulsein_obj_t *self, bool rising, bool falling) {
|
||||
ETS_GPIO_INTR_DISABLE();
|
||||
// Set interrupt mode
|
||||
GPIO_REG_WRITE(
|
||||
GPIO_PIN_ADDR(self->pin->gpio_number),
|
||||
(GPIO_REG_READ(GPIO_PIN_ADDR(self->pin->gpio_number) & ~GPIO_PIN_INT_TYPE_MASK)) |
|
||||
GPIO_PIN_INT_TYPE_SET(
|
||||
(rising ? GPIO_PIN_INTR_POSEDGE : 0) | (falling ? GPIO_PIN_INTR_NEGEDGE : 0)
|
||||
)
|
||||
);
|
||||
// Clear interrupt status
|
||||
GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, 1 << self->pin->gpio_number);
|
||||
ETS_GPIO_INTR_ENABLE();
|
||||
}
|
||||
|
||||
void pulseio_pulsein_interrupt_handler(void *data) {
|
||||
pulseio_pulsein_obj_t *self = data;
|
||||
uint32_t time_us = system_get_time();
|
||||
if (self->first_edge) {
|
||||
self->first_edge = false;
|
||||
pulsein_set_interrupt(self, true, true);
|
||||
} else {
|
||||
uint16_t elapsed_us = (uint16_t)(time_us - self->last_us);
|
||||
uint16_t i = (self->start + self->len) % self->maxlen;
|
||||
self->buffer[i] = elapsed_us;
|
||||
if (self->len < self->maxlen) {
|
||||
self->len++;
|
||||
} else {
|
||||
self->start++;
|
||||
}
|
||||
}
|
||||
self->last_us = time_us;
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pulsein_construct(pulseio_pulsein_obj_t* self,
|
||||
const mcu_pin_obj_t* pin, uint16_t maxlen, bool idle_state) {
|
||||
if (pin->gpio_number == NO_GPIO || pin->gpio_function == SPECIAL_CASE) {
|
||||
mp_raise_msg_varg(&mp_type_ValueError, translate("No PulseIn support for %q"), pin->name );
|
||||
}
|
||||
PIN_FUNC_SELECT(pin->peripheral, pin->gpio_function);
|
||||
PIN_PULLUP_DIS(pin->peripheral);
|
||||
self->pin = pin;
|
||||
|
||||
self->buffer = (uint16_t *) m_malloc(maxlen * sizeof(uint16_t), false);
|
||||
if (self->buffer == NULL) {
|
||||
mp_raise_msg_varg(&mp_type_MemoryError, translate("Failed to allocate RX buffer of %d bytes"), maxlen * sizeof(uint16_t));
|
||||
}
|
||||
|
||||
self->maxlen = maxlen;
|
||||
self->idle_state = idle_state;
|
||||
self->start = 0;
|
||||
self->len = 0;
|
||||
self->first_edge = true;
|
||||
self->last_us = 0;
|
||||
self->paused = false;
|
||||
|
||||
microcontroller_pin_register_intr_handler(self->pin->gpio_number,
|
||||
pulseio_pulsein_interrupt_handler, (void *)self);
|
||||
pulsein_set_interrupt(self, !idle_state, idle_state);
|
||||
}
|
||||
|
||||
bool common_hal_pulseio_pulsein_deinited(pulseio_pulsein_obj_t* self) {
|
||||
return self->buffer == NULL;
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pulsein_deinit(pulseio_pulsein_obj_t* self) {
|
||||
pulsein_set_interrupt(self, false, false);
|
||||
microcontroller_pin_register_intr_handler(self->pin->gpio_number, NULL, NULL);
|
||||
PIN_FUNC_SELECT(self->pin->peripheral, 0);
|
||||
m_free(self->buffer);
|
||||
self->buffer = NULL;
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pulsein_pause(pulseio_pulsein_obj_t* self) {
|
||||
pulsein_set_interrupt(self, false, false);
|
||||
self->paused = true;
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pulsein_resume(pulseio_pulsein_obj_t* self,
|
||||
uint16_t trigger_duration) {
|
||||
// Make sure we're paused.
|
||||
common_hal_pulseio_pulsein_pause(self);
|
||||
|
||||
// Send the trigger pulse.
|
||||
if (trigger_duration > 0) {
|
||||
uint32_t mask = 1 << self->pin->gpio_number;
|
||||
// switch pin to an output with state opposite idle state
|
||||
gpio_output_set(self->idle_state ? 0 : mask, self->idle_state ? mask : 0, 0, 0);
|
||||
gpio_output_set(0, 0, mask, 0);
|
||||
common_hal_mcu_delay_us((uint32_t)trigger_duration);
|
||||
// switch pin back to an open input
|
||||
gpio_output_set(0, 0, 0, mask);
|
||||
}
|
||||
|
||||
common_hal_mcu_disable_interrupts();
|
||||
self->first_edge = true;
|
||||
pulsein_set_interrupt(self, !self->idle_state, self->idle_state);
|
||||
common_hal_mcu_enable_interrupts();
|
||||
self->paused = false;
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pulsein_clear(pulseio_pulsein_obj_t* self) {
|
||||
common_hal_mcu_disable_interrupts();
|
||||
self->start = 0;
|
||||
self->len = 0;
|
||||
common_hal_mcu_enable_interrupts();
|
||||
}
|
||||
|
||||
uint16_t common_hal_pulseio_pulsein_popleft(pulseio_pulsein_obj_t* self) {
|
||||
if (self->len == 0) {
|
||||
mp_raise_IndexError(translate("pop from an empty PulseIn"));
|
||||
}
|
||||
common_hal_mcu_disable_interrupts();
|
||||
uint16_t value = self->buffer[self->start];
|
||||
self->start = (self->start + 1) % self->maxlen;
|
||||
self->len--;
|
||||
common_hal_mcu_enable_interrupts();
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
uint16_t common_hal_pulseio_pulsein_get_maxlen(pulseio_pulsein_obj_t* self) {
|
||||
return self->maxlen;
|
||||
}
|
||||
|
||||
bool common_hal_pulseio_pulsein_get_paused(pulseio_pulsein_obj_t* self) {
|
||||
return self->paused;
|
||||
}
|
||||
|
||||
uint16_t common_hal_pulseio_pulsein_get_len(pulseio_pulsein_obj_t* self) {
|
||||
return self->len;
|
||||
}
|
||||
|
||||
uint16_t common_hal_pulseio_pulsein_get_item(pulseio_pulsein_obj_t* self,
|
||||
int16_t index) {
|
||||
common_hal_mcu_disable_interrupts();
|
||||
if (index < 0) {
|
||||
index += self->len;
|
||||
}
|
||||
if (index < 0 || index >= self->len) {
|
||||
common_hal_mcu_enable_interrupts();
|
||||
mp_raise_IndexError(translate("index out of range"));
|
||||
}
|
||||
uint16_t value = self->buffer[(self->start + index) % self->maxlen];
|
||||
common_hal_mcu_enable_interrupts();
|
||||
return value;
|
||||
}
|
@ -1,50 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* 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_ESP8266_COMMON_HAL_PULSEIO_PULSEIN_H
|
||||
#define MICROPY_INCLUDED_ESP8266_COMMON_HAL_PULSEIO_PULSEIN_H
|
||||
|
||||
#include "py/obj.h"
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
const mcu_pin_obj_t *pin;
|
||||
uint16_t *buffer;
|
||||
uint16_t maxlen;
|
||||
bool idle_state;
|
||||
bool paused;
|
||||
volatile uint16_t start;
|
||||
volatile uint16_t len;
|
||||
volatile bool first_edge;
|
||||
volatile uint32_t last_us;
|
||||
} pulseio_pulsein_obj_t;
|
||||
|
||||
void pulsein_reset(void);
|
||||
|
||||
void pulsein_interrupt_handler(uint32_t);
|
||||
|
||||
#endif // MICROPY_INCLUDED_ESP8266_COMMON_HAL_PULSEIO_PULSEIN_H
|
@ -1,64 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* 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 "common-hal/pulseio/PulseOut.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <pwm.h>
|
||||
|
||||
#include "ets_alt_task.h"
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "mpconfigport.h"
|
||||
#include "shared-bindings/pulseio/PulseOut.h"
|
||||
|
||||
void pulseout_set(pulseio_pulseout_obj_t *self, bool state) {
|
||||
PIN_FUNC_SELECT(self->pin->peripheral, state ? self->pin->gpio_function : 0);
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pulseout_construct(pulseio_pulseout_obj_t* self,
|
||||
const pulseio_pwmout_obj_t* carrier) {
|
||||
self->pin = carrier->pin;
|
||||
}
|
||||
|
||||
bool common_hal_pulseio_pulseout_deinited(pulseio_pulseout_obj_t* self) {
|
||||
return self->pin == NULL;
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pulseout_deinit(pulseio_pulseout_obj_t* self) {
|
||||
self->pin = NULL;
|
||||
pulseout_set(self, true);
|
||||
}
|
||||
|
||||
void common_hal_pulseio_pulseout_send(pulseio_pulseout_obj_t* self,
|
||||
uint16_t* pulses, uint16_t length) {
|
||||
for (uint16_t i = 0; i<length; i++) {
|
||||
pulseout_set(self, i % 2 == 0);
|
||||
ets_delay_us(pulses[i]);
|
||||
}
|
||||
pulseout_set(self, false);
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* 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_ESP8266_COMMON_HAL_PULSEIO_PULSEOUT_H
|
||||
#define MICROPY_INCLUDED_ESP8266_COMMON_HAL_PULSEIO_PULSEOUT_H
|
||||
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
|
||||
#include "esp_mphal.h"
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
typedef struct {
|
||||
mp_obj_base_t base;
|
||||
os_timer_t timer;
|
||||
const mcu_pin_obj_t *pin;
|
||||
} pulseio_pulseout_obj_t;
|
||||
|
||||
void pulseout_reset(void);
|
||||
void pulseout_interrupt_handler(void *);
|
||||
|
||||
#endif // MICROPY_INCLUDED_ESP8266_COMMON_HAL_PULSEIO_PULSEOUT_H
|
@ -1 +0,0 @@
|
||||
// No pulseio module functions.
|
@ -1,39 +0,0 @@
|
||||
/*
|
||||
* This file is part of the Micro Python project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2017 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "py/runtime.h"
|
||||
#include "shared-bindings/storage/__init__.h"
|
||||
#include "supervisor/shared/translate.h"
|
||||
|
||||
void common_hal_storage_remount(const char* mount_path, bool readonly) {
|
||||
mp_raise_NotImplementedError(translate("Unable to remount filesystem"));
|
||||
}
|
||||
|
||||
void common_hal_storage_erase_filesystem() {
|
||||
mp_raise_NotImplementedError(translate("Use esptool to erase flash and re-upload Python instead"));
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 Scott Shawcroft for Adafruit Industries
|
||||
*
|
||||
* 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 "py/mphal.h"
|
||||
|
||||
#include "shared-bindings/time/__init__.h"
|
||||
|
||||
#include "ets_alt_task.h"
|
||||
#include "user_interface.h"
|
||||
|
||||
inline uint64_t common_hal_time_monotonic() {
|
||||
return ((uint64_t)system_time_high_word << 32 | (uint64_t)system_get_time()) / 1000;
|
||||
}
|
||||
|
||||
void common_hal_time_delay_ms(uint32_t delay) {
|
||||
mp_hal_delay_ms(delay);
|
||||
}
|
@ -1,351 +0,0 @@
|
||||
PROVIDE ( Cache_Read_Disable = 0x400047f0 );
|
||||
PROVIDE ( Cache_Read_Enable = 0x40004678 );
|
||||
PROVIDE ( FilePacketSendReqMsgProc = 0x400035a0 );
|
||||
PROVIDE ( FlashDwnLdParamCfgMsgProc = 0x4000368c );
|
||||
PROVIDE ( FlashDwnLdStartMsgProc = 0x40003538 );
|
||||
PROVIDE ( FlashDwnLdStopReqMsgProc = 0x40003658 );
|
||||
PROVIDE ( GetUartDevice = 0x40003f4c );
|
||||
PROVIDE ( MD5Final = 0x40009900 );
|
||||
PROVIDE ( MD5Init = 0x40009818 );
|
||||
PROVIDE ( MD5Update = 0x40009834 );
|
||||
PROVIDE ( MemDwnLdStartMsgProc = 0x400036c4 );
|
||||
PROVIDE ( MemDwnLdStopReqMsgProc = 0x4000377c );
|
||||
PROVIDE ( MemPacketSendReqMsgProc = 0x400036f0 );
|
||||
PROVIDE ( RcvMsg = 0x40003eac );
|
||||
PROVIDE ( SHA1Final = 0x4000b648 );
|
||||
PROVIDE ( SHA1Init = 0x4000b584 );
|
||||
PROVIDE ( SHA1Transform = 0x4000a364 );
|
||||
PROVIDE ( SHA1Update = 0x4000b5a8 );
|
||||
PROVIDE ( SPI_read_status = 0x400043c8 );
|
||||
PROVIDE ( SPI_write_status = 0x40004400 );
|
||||
PROVIDE ( SPI_write_enable = 0x4000443c );
|
||||
PROVIDE ( Wait_SPI_Idle = 0x4000448c );
|
||||
PROVIDE ( Enable_QMode = 0x400044c0 );
|
||||
PROVIDE ( SPIEraseArea = 0x40004b44 );
|
||||
PROVIDE ( SPIEraseBlock = 0x400049b4 );
|
||||
PROVIDE ( SPIEraseChip = 0x40004984 );
|
||||
PROVIDE ( SPIEraseSector = 0x40004a00 );
|
||||
PROVIDE ( SPILock = 0x400048a8 );
|
||||
PROVIDE ( SPIParamCfg = 0x40004c2c );
|
||||
PROVIDE ( SPIRead = 0x40004b1c );
|
||||
PROVIDE ( SPIReadModeCnfig = 0x400048ec );
|
||||
PROVIDE ( SPIUnlock = 0x40004878 );
|
||||
PROVIDE ( SPIWrite = 0x40004a4c );
|
||||
PROVIDE ( SelectSpiFunction = 0x40003f58 );
|
||||
PROVIDE ( SendMsg = 0x40003cf4 );
|
||||
PROVIDE ( UartConnCheck = 0x40003230 );
|
||||
PROVIDE ( UartConnectProc = 0x400037a0 );
|
||||
PROVIDE ( UartDwnLdProc = 0x40003368 );
|
||||
PROVIDE ( UartGetCmdLn = 0x40003ef4 );
|
||||
PROVIDE ( UartRegReadProc = 0x4000381c );
|
||||
PROVIDE ( UartRegWriteProc = 0x400037ac );
|
||||
PROVIDE ( UartRxString = 0x40003c30 );
|
||||
PROVIDE ( Uart_Init = 0x40003a14 );
|
||||
PROVIDE ( _DebugExceptionVector = 0x40000010 );
|
||||
PROVIDE ( _DoubleExceptionVector = 0x40000070 );
|
||||
PROVIDE ( _KernelExceptionVector = 0x40000030 );
|
||||
PROVIDE ( _NMIExceptionVector = 0x40000020 );
|
||||
PROVIDE ( _ResetHandler = 0x400000a4 );
|
||||
PROVIDE ( _ResetVector = 0x40000080 );
|
||||
PROVIDE ( _UserExceptionVector = 0x40000050 );
|
||||
__adddf3 = 0x4000c538;
|
||||
__addsf3 = 0x4000c180;
|
||||
__divdf3 = 0x4000cb94;
|
||||
__divdi3 = 0x4000ce60;
|
||||
__divsi3 = 0x4000dc88;
|
||||
__extendsfdf2 = 0x4000cdfc;
|
||||
__fixdfsi = 0x4000ccb8;
|
||||
__fixunsdfsi = 0x4000cd00;
|
||||
__fixunssfsi = 0x4000c4c4;
|
||||
__floatsidf = 0x4000e2f0;
|
||||
__floatsisf = 0x4000e2ac;
|
||||
__floatunsidf = 0x4000e2e8;
|
||||
__floatunsisf = 0x4000e2a4;
|
||||
__muldf3 = 0x4000c8f0;
|
||||
__muldi3 = 0x40000650;
|
||||
__mulsf3 = 0x4000c3dc;
|
||||
__subdf3 = 0x4000c688;
|
||||
__subsf3 = 0x4000c268;
|
||||
__truncdfsf2 = 0x4000cd5c;
|
||||
__udivdi3 = 0x4000d310;
|
||||
__udivsi3 = 0x4000e21c;
|
||||
__umoddi3 = 0x4000d770;
|
||||
__umodsi3 = 0x4000e268;
|
||||
__umulsidi3 = 0x4000dcf0;
|
||||
PROVIDE ( _rom_store = 0x4000e388 );
|
||||
PROVIDE ( _rom_store_table = 0x4000e328 );
|
||||
PROVIDE ( _start = 0x4000042c );
|
||||
PROVIDE ( _xtos_alloca_handler = 0x4000dbe0 );
|
||||
PROVIDE ( _xtos_c_wrapper_handler = 0x40000598 );
|
||||
PROVIDE ( _xtos_cause3_handler = 0x40000590 );
|
||||
PROVIDE ( _xtos_ints_off = 0x4000bda4 );
|
||||
PROVIDE ( _xtos_ints_on = 0x4000bd84 );
|
||||
PROVIDE ( _xtos_l1int_handler = 0x4000048c );
|
||||
PROVIDE ( _xtos_p_none = 0x4000dbf8 );
|
||||
PROVIDE ( _xtos_restore_intlevel = 0x4000056c );
|
||||
PROVIDE ( _xtos_return_from_exc = 0x4000dc54 );
|
||||
PROVIDE ( _xtos_set_exception_handler = 0x40000454 );
|
||||
PROVIDE ( _xtos_set_interrupt_handler = 0x4000bd70 );
|
||||
PROVIDE ( _xtos_set_interrupt_handler_arg = 0x4000bd28 );
|
||||
PROVIDE ( _xtos_set_intlevel = 0x4000dbfc );
|
||||
PROVIDE ( _xtos_set_min_intlevel = 0x4000dc18 );
|
||||
PROVIDE ( _xtos_set_vpri = 0x40000574 );
|
||||
PROVIDE ( _xtos_syscall_handler = 0x4000dbe4 );
|
||||
PROVIDE ( _xtos_unhandled_exception = 0x4000dc44 );
|
||||
PROVIDE ( _xtos_unhandled_interrupt = 0x4000dc3c );
|
||||
PROVIDE ( aes_decrypt = 0x400092d4 );
|
||||
PROVIDE ( aes_decrypt_deinit = 0x400092e4 );
|
||||
PROVIDE ( aes_decrypt_init = 0x40008ea4 );
|
||||
PROVIDE ( aes_unwrap = 0x40009410 );
|
||||
PROVIDE ( base64_decode = 0x40009648 );
|
||||
PROVIDE ( base64_encode = 0x400094fc );
|
||||
PROVIDE ( bzero = 0x4000de84 );
|
||||
PROVIDE ( cmd_parse = 0x40000814 );
|
||||
PROVIDE ( conv_str_decimal = 0x40000b24 );
|
||||
PROVIDE ( conv_str_hex = 0x40000cb8 );
|
||||
PROVIDE ( convert_para_str = 0x40000a60 );
|
||||
PROVIDE ( dtm_get_intr_mask = 0x400026d0 );
|
||||
PROVIDE ( dtm_params_init = 0x4000269c );
|
||||
PROVIDE ( dtm_set_intr_mask = 0x400026c8 );
|
||||
PROVIDE ( dtm_set_params = 0x400026dc );
|
||||
PROVIDE ( eprintf = 0x40001d14 );
|
||||
PROVIDE ( eprintf_init_buf = 0x40001cb8 );
|
||||
PROVIDE ( eprintf_to_host = 0x40001d48 );
|
||||
PROVIDE ( est_get_printf_buf_remain_len = 0x40002494 );
|
||||
PROVIDE ( est_reset_printf_buf_len = 0x4000249c );
|
||||
PROVIDE ( ets_bzero = 0x40002ae8 );
|
||||
PROVIDE ( ets_char2xdigit = 0x40002b74 );
|
||||
PROVIDE ( ets_delay_us = 0x40002ecc );
|
||||
PROVIDE ( ets_enter_sleep = 0x400027b8 );
|
||||
PROVIDE ( ets_external_printf = 0x40002578 );
|
||||
PROVIDE ( ets_get_cpu_frequency = 0x40002f0c );
|
||||
PROVIDE ( ets_getc = 0x40002bcc );
|
||||
PROVIDE ( ets_install_external_printf = 0x40002450 );
|
||||
PROVIDE ( ets_install_putc1 = 0x4000242c );
|
||||
PROVIDE ( ets_install_putc2 = 0x4000248c );
|
||||
PROVIDE ( ets_install_uart_printf = 0x40002438 );
|
||||
PROVIDE ( ets_intr_lock = 0x40000f74 );
|
||||
PROVIDE ( ets_intr_unlock = 0x40000f80 );
|
||||
PROVIDE ( ets_isr_attach = 0x40000f88 );
|
||||
PROVIDE ( ets_isr_mask = 0x40000f98 );
|
||||
PROVIDE ( ets_isr_unmask = 0x40000fa8 );
|
||||
PROVIDE ( ets_memcmp = 0x400018d4 );
|
||||
PROVIDE ( ets_memcpy = 0x400018b4 );
|
||||
PROVIDE ( ets_memmove = 0x400018c4 );
|
||||
PROVIDE ( ets_memset = 0x400018a4 );
|
||||
PROVIDE ( _ets_post = 0x40000e24 );
|
||||
PROVIDE ( ets_printf = 0x400024cc );
|
||||
PROVIDE ( ets_putc = 0x40002be8 );
|
||||
PROVIDE ( ets_rtc_int_register = 0x40002a40 );
|
||||
PROVIDE ( _ets_run = 0x40000e04 );
|
||||
PROVIDE ( _ets_set_idle_cb = 0x40000dc0 );
|
||||
PROVIDE ( ets_set_user_start = 0x40000fbc );
|
||||
PROVIDE ( ets_str2macaddr = 0x40002af8 );
|
||||
PROVIDE ( ets_strcmp = 0x40002aa8 );
|
||||
PROVIDE ( ets_strcpy = 0x40002a88 );
|
||||
PROVIDE ( ets_strlen = 0x40002ac8 );
|
||||
PROVIDE ( ets_strncmp = 0x40002ab8 );
|
||||
PROVIDE ( ets_strncpy = 0x40002a98 );
|
||||
PROVIDE ( ets_strstr = 0x40002ad8 );
|
||||
PROVIDE ( _ets_task = 0x40000dd0 );
|
||||
PROVIDE ( ets_timer_arm = 0x40002cc4 );
|
||||
PROVIDE ( ets_timer_disarm = 0x40002d40 );
|
||||
PROVIDE ( ets_timer_done = 0x40002d80 );
|
||||
PROVIDE ( ets_timer_handler_isr = 0x40002da8 );
|
||||
PROVIDE ( _ets_timer_init = 0x40002e68 );
|
||||
PROVIDE ( ets_timer_setfn = 0x40002c48 );
|
||||
PROVIDE ( ets_uart_printf = 0x40002544 );
|
||||
PROVIDE ( ets_update_cpu_frequency = 0x40002f04 );
|
||||
PROVIDE ( ets_vprintf = 0x40001f00 );
|
||||
PROVIDE ( ets_wdt_disable = 0x400030f0 );
|
||||
PROVIDE ( ets_wdt_enable = 0x40002fa0 );
|
||||
PROVIDE ( ets_wdt_get_mode = 0x40002f34 );
|
||||
PROVIDE ( ets_wdt_init = 0x40003170 );
|
||||
PROVIDE ( ets_wdt_restore = 0x40003158 );
|
||||
PROVIDE ( ets_write_char = 0x40001da0 );
|
||||
PROVIDE ( get_first_seg = 0x4000091c );
|
||||
PROVIDE ( gpio_init = 0x40004c50 );
|
||||
PROVIDE ( gpio_input_get = 0x40004cf0 );
|
||||
PROVIDE ( gpio_intr_ack = 0x40004dcc );
|
||||
PROVIDE ( gpio_intr_handler_register = 0x40004e28 );
|
||||
PROVIDE ( gpio_intr_pending = 0x40004d88 );
|
||||
PROVIDE ( gpio_intr_test = 0x40004efc );
|
||||
PROVIDE ( gpio_output_set = 0x40004cd0 );
|
||||
PROVIDE ( gpio_pin_intr_state_set = 0x40004d90 );
|
||||
PROVIDE ( gpio_pin_wakeup_disable = 0x40004ed4 );
|
||||
PROVIDE ( gpio_pin_wakeup_enable = 0x40004e90 );
|
||||
PROVIDE ( gpio_register_get = 0x40004d5c );
|
||||
PROVIDE ( gpio_register_set = 0x40004d04 );
|
||||
PROVIDE ( hmac_md5 = 0x4000a2cc );
|
||||
PROVIDE ( hmac_md5_vector = 0x4000a160 );
|
||||
PROVIDE ( hmac_sha1 = 0x4000ba28 );
|
||||
PROVIDE ( hmac_sha1_vector = 0x4000b8b4 );
|
||||
PROVIDE ( lldesc_build_chain = 0x40004f40 );
|
||||
PROVIDE ( lldesc_num2link = 0x40005050 );
|
||||
PROVIDE ( lldesc_set_owner = 0x4000507c );
|
||||
PROVIDE ( main = 0x40000fec );
|
||||
PROVIDE ( md5_vector = 0x400097ac );
|
||||
PROVIDE ( mem_calloc = 0x40001c2c );
|
||||
PROVIDE ( mem_free = 0x400019e0 );
|
||||
PROVIDE ( mem_init = 0x40001998 );
|
||||
PROVIDE ( mem_malloc = 0x40001b40 );
|
||||
PROVIDE ( mem_realloc = 0x40001c6c );
|
||||
PROVIDE ( mem_trim = 0x40001a14 );
|
||||
PROVIDE ( mem_zalloc = 0x40001c58 );
|
||||
PROVIDE ( memcmp = 0x4000dea8 );
|
||||
PROVIDE ( memcpy = 0x4000df48 );
|
||||
PROVIDE ( memmove = 0x4000e04c );
|
||||
PROVIDE ( memset = 0x4000e190 );
|
||||
PROVIDE ( multofup = 0x400031c0 );
|
||||
PROVIDE ( pbkdf2_sha1 = 0x4000b840 );
|
||||
PROVIDE ( phy_get_romfuncs = 0x40006b08 );
|
||||
PROVIDE ( rand = 0x40000600 );
|
||||
PROVIDE ( rc4_skip = 0x4000dd68 );
|
||||
PROVIDE ( recv_packet = 0x40003d08 );
|
||||
PROVIDE ( remove_head_space = 0x40000a04 );
|
||||
PROVIDE ( rijndaelKeySetupDec = 0x40008dd0 );
|
||||
PROVIDE ( rijndaelKeySetupEnc = 0x40009300 );
|
||||
PROVIDE ( rom_abs_temp = 0x400060c0 );
|
||||
PROVIDE ( rom_ana_inf_gating_en = 0x40006b10 );
|
||||
PROVIDE ( rom_cal_tos_v50 = 0x40007a28 );
|
||||
PROVIDE ( rom_chip_50_set_channel = 0x40006f84 );
|
||||
PROVIDE ( rom_chip_v5_disable_cca = 0x400060d0 );
|
||||
PROVIDE ( rom_chip_v5_enable_cca = 0x400060ec );
|
||||
PROVIDE ( rom_chip_v5_rx_init = 0x4000711c );
|
||||
PROVIDE ( rom_chip_v5_sense_backoff = 0x4000610c );
|
||||
PROVIDE ( rom_chip_v5_tx_init = 0x4000718c );
|
||||
PROVIDE ( rom_dc_iq_est = 0x4000615c );
|
||||
PROVIDE ( rom_en_pwdet = 0x400061b8 );
|
||||
PROVIDE ( rom_get_bb_atten = 0x40006238 );
|
||||
PROVIDE ( rom_get_corr_power = 0x40006260 );
|
||||
PROVIDE ( rom_get_fm_sar_dout = 0x400062dc );
|
||||
PROVIDE ( rom_get_noisefloor = 0x40006394 );
|
||||
PROVIDE ( rom_get_power_db = 0x400063b0 );
|
||||
PROVIDE ( rom_i2c_readReg = 0x40007268 );
|
||||
PROVIDE ( rom_i2c_readReg_Mask = 0x4000729c );
|
||||
PROVIDE ( rom_i2c_writeReg = 0x400072d8 );
|
||||
PROVIDE ( rom_i2c_writeReg_Mask = 0x4000730c );
|
||||
PROVIDE ( rom_iq_est_disable = 0x40006400 );
|
||||
PROVIDE ( rom_iq_est_enable = 0x40006430 );
|
||||
PROVIDE ( rom_linear_to_db = 0x40006484 );
|
||||
PROVIDE ( rom_mhz2ieee = 0x400065a4 );
|
||||
PROVIDE ( rom_pbus_dco___SA2 = 0x40007bf0 );
|
||||
PROVIDE ( rom_pbus_debugmode = 0x4000737c );
|
||||
PROVIDE ( rom_pbus_enter_debugmode = 0x40007410 );
|
||||
PROVIDE ( rom_pbus_exit_debugmode = 0x40007448 );
|
||||
PROVIDE ( rom_pbus_force_test = 0x4000747c );
|
||||
PROVIDE ( rom_pbus_rd = 0x400074d8 );
|
||||
PROVIDE ( rom_pbus_set_rxgain = 0x4000754c );
|
||||
PROVIDE ( rom_pbus_set_txgain = 0x40007610 );
|
||||
PROVIDE ( rom_pbus_workmode = 0x40007648 );
|
||||
PROVIDE ( rom_pbus_xpd_rx_off = 0x40007688 );
|
||||
PROVIDE ( rom_pbus_xpd_rx_on = 0x400076cc );
|
||||
PROVIDE ( rom_pbus_xpd_tx_off = 0x400076fc );
|
||||
PROVIDE ( rom_pbus_xpd_tx_on = 0x40007740 );
|
||||
PROVIDE ( rom_pbus_xpd_tx_on__low_gain = 0x400077a0 );
|
||||
PROVIDE ( rom_phy_reset_req = 0x40007804 );
|
||||
PROVIDE ( rom_restart_cal = 0x4000781c );
|
||||
PROVIDE ( rom_rfcal_pwrctrl = 0x40007eb4 );
|
||||
PROVIDE ( rom_rfcal_rxiq = 0x4000804c );
|
||||
PROVIDE ( rom_rfcal_rxiq_set_reg = 0x40008264 );
|
||||
PROVIDE ( rom_rfcal_txcap = 0x40008388 );
|
||||
PROVIDE ( rom_rfcal_txiq = 0x40008610 );
|
||||
PROVIDE ( rom_rfcal_txiq_cover = 0x400088b8 );
|
||||
PROVIDE ( rom_rfcal_txiq_set_reg = 0x40008a70 );
|
||||
PROVIDE ( rom_rfpll_reset = 0x40007868 );
|
||||
PROVIDE ( rom_rfpll_set_freq = 0x40007968 );
|
||||
PROVIDE ( rom_rxiq_cover_mg_mp = 0x40008b6c );
|
||||
PROVIDE ( rom_rxiq_get_mis = 0x40006628 );
|
||||
PROVIDE ( rom_sar_init = 0x40006738 );
|
||||
PROVIDE ( rom_set_ana_inf_tx_scale = 0x4000678c );
|
||||
PROVIDE ( rom_set_channel_freq = 0x40006c50 );
|
||||
PROVIDE ( rom_set_loopback_gain = 0x400067c8 );
|
||||
PROVIDE ( rom_set_noise_floor = 0x40006830 );
|
||||
PROVIDE ( rom_set_rxclk_en = 0x40006550 );
|
||||
PROVIDE ( rom_set_txbb_atten = 0x40008c6c );
|
||||
PROVIDE ( rom_set_txclk_en = 0x4000650c );
|
||||
PROVIDE ( rom_set_txiq_cal = 0x40008d34 );
|
||||
PROVIDE ( rom_start_noisefloor = 0x40006874 );
|
||||
PROVIDE ( rom_start_tx_tone = 0x400068b4 );
|
||||
PROVIDE ( rom_stop_tx_tone = 0x4000698c );
|
||||
PROVIDE ( rom_tx_mac_disable = 0x40006a98 );
|
||||
PROVIDE ( rom_tx_mac_enable = 0x40006ad4 );
|
||||
PROVIDE ( rom_txtone_linear_pwr = 0x40006a1c );
|
||||
PROVIDE ( rom_write_rfpll_sdm = 0x400078dc );
|
||||
PROVIDE ( roundup2 = 0x400031b4 );
|
||||
PROVIDE ( rtc_enter_sleep = 0x40002870 );
|
||||
PROVIDE ( rtc_get_reset_reason = 0x400025e0 );
|
||||
PROVIDE ( rtc_intr_handler = 0x400029ec );
|
||||
PROVIDE ( rtc_set_sleep_mode = 0x40002668 );
|
||||
PROVIDE ( save_rxbcn_mactime = 0x400027a4 );
|
||||
PROVIDE ( save_tsf_us = 0x400027ac );
|
||||
PROVIDE ( send_packet = 0x40003c80 );
|
||||
PROVIDE ( sha1_prf = 0x4000ba48 );
|
||||
PROVIDE ( sha1_vector = 0x4000a2ec );
|
||||
PROVIDE ( sip_alloc_to_host_evt = 0x40005180 );
|
||||
PROVIDE ( sip_get_ptr = 0x400058a8 );
|
||||
PROVIDE ( sip_get_state = 0x40005668 );
|
||||
PROVIDE ( sip_init_attach = 0x4000567c );
|
||||
PROVIDE ( sip_install_rx_ctrl_cb = 0x4000544c );
|
||||
PROVIDE ( sip_install_rx_data_cb = 0x4000545c );
|
||||
PROVIDE ( sip_post = 0x400050fc );
|
||||
PROVIDE ( sip_post_init = 0x400056c4 );
|
||||
PROVIDE ( sip_reclaim_from_host_cmd = 0x4000534c );
|
||||
PROVIDE ( sip_reclaim_tx_data_pkt = 0x400052c0 );
|
||||
PROVIDE ( sip_send = 0x40005808 );
|
||||
PROVIDE ( sip_to_host_chain_append = 0x40005864 );
|
||||
PROVIDE ( sip_to_host_evt_send_done = 0x40005234 );
|
||||
PROVIDE ( slc_add_credits = 0x400060ac );
|
||||
PROVIDE ( slc_enable = 0x40005d90 );
|
||||
PROVIDE ( slc_from_host_chain_fetch = 0x40005f24 );
|
||||
PROVIDE ( slc_from_host_chain_recycle = 0x40005e94 );
|
||||
PROVIDE ( slc_init_attach = 0x40005c50 );
|
||||
PROVIDE ( slc_init_credit = 0x4000608c );
|
||||
PROVIDE ( slc_pause_from_host = 0x40006014 );
|
||||
PROVIDE ( slc_reattach = 0x40005c1c );
|
||||
PROVIDE ( slc_resume_from_host = 0x4000603c );
|
||||
PROVIDE ( slc_select_tohost_gpio = 0x40005dc0 );
|
||||
PROVIDE ( slc_select_tohost_gpio_mode = 0x40005db8 );
|
||||
PROVIDE ( slc_send_to_host_chain = 0x40005de4 );
|
||||
PROVIDE ( slc_set_host_io_max_window = 0x40006068 );
|
||||
PROVIDE ( slc_to_host_chain_recycle = 0x40005f10 );
|
||||
PROVIDE ( software_reset = 0x4000264c );
|
||||
PROVIDE ( spi_flash_attach = 0x40004644 );
|
||||
PROVIDE ( srand = 0x400005f0 );
|
||||
PROVIDE ( strcmp = 0x4000bdc8 );
|
||||
PROVIDE ( strcpy = 0x4000bec8 );
|
||||
PROVIDE ( strlen = 0x4000bf4c );
|
||||
PROVIDE ( strncmp = 0x4000bfa8 );
|
||||
PROVIDE ( strncpy = 0x4000c0a0 );
|
||||
PROVIDE ( strstr = 0x4000e1e0 );
|
||||
PROVIDE ( timer_insert = 0x40002c64 );
|
||||
PROVIDE ( uartAttach = 0x4000383c );
|
||||
PROVIDE ( uart_baudrate_detect = 0x40003924 );
|
||||
PROVIDE ( uart_buff_switch = 0x400038a4 );
|
||||
PROVIDE ( uart_div_modify = 0x400039d8 );
|
||||
PROVIDE ( uart_rx_intr_handler = 0x40003bbc );
|
||||
PROVIDE ( uart_rx_one_char = 0x40003b8c );
|
||||
PROVIDE ( uart_rx_one_char_block = 0x40003b64 );
|
||||
PROVIDE ( uart_rx_readbuff = 0x40003ec8 );
|
||||
PROVIDE ( uart_tx_one_char = 0x40003b30 );
|
||||
PROVIDE ( wepkey_128 = 0x4000bc40 );
|
||||
PROVIDE ( wepkey_64 = 0x4000bb3c );
|
||||
PROVIDE ( xthal_bcopy = 0x40000688 );
|
||||
PROVIDE ( xthal_copy123 = 0x4000074c );
|
||||
PROVIDE ( xthal_get_ccompare = 0x4000dd4c );
|
||||
PROVIDE ( xthal_get_ccount = 0x4000dd38 );
|
||||
PROVIDE ( xthal_get_interrupt = 0x4000dd58 );
|
||||
PROVIDE ( xthal_get_intread = 0x4000dd58 );
|
||||
PROVIDE ( xthal_memcpy = 0x400006c4 );
|
||||
PROVIDE ( xthal_set_ccompare = 0x4000dd40 );
|
||||
PROVIDE ( xthal_set_intclear = 0x4000dd60 );
|
||||
PROVIDE ( xthal_spill_registers_into_stack_nw = 0x4000e320 );
|
||||
PROVIDE ( xthal_window_spill = 0x4000e324 );
|
||||
PROVIDE ( xthal_window_spill_nw = 0x4000e320 );
|
||||
|
||||
PROVIDE ( Te0 = 0x3fffccf0 );
|
||||
PROVIDE ( Td0 = 0x3fffd100 );
|
||||
PROVIDE ( Td4s = 0x3fffd500);
|
||||
PROVIDE ( rcons = 0x3fffd0f0);
|
||||
PROVIDE ( UartDev = 0x3fffde10 );
|
||||
PROVIDE ( flashchip = 0x3fffc714);
|
@ -1,12 +0,0 @@
|
||||
/* GNU linker script for ESP8266 */
|
||||
|
||||
MEMORY
|
||||
{
|
||||
dport0_0_seg : org = 0x3ff00000, len = 0x10
|
||||
dram0_0_seg : org = 0x3ffe8000, len = 0x14000
|
||||
iram1_0_seg : org = 0x40100000, len = 0x8000
|
||||
irom0_0_seg : org = 0x40209000, len = 0x91000
|
||||
}
|
||||
|
||||
/* define common sections and symbols */
|
||||
INCLUDE esp8266_common.ld
|
@ -1,12 +0,0 @@
|
||||
/* GNU linker script for ESP8266 */
|
||||
|
||||
MEMORY
|
||||
{
|
||||
dport0_0_seg : org = 0x3ff00000, len = 0x10
|
||||
dram0_0_seg : org = 0x3ffe8000, len = 0x14000
|
||||
iram1_0_seg : org = 0x40100000, len = 0x8000
|
||||
irom0_0_seg : org = 0x40209000, len = 0x72000
|
||||
}
|
||||
|
||||
/* define common sections and symbols */
|
||||
INCLUDE esp8266_common.ld
|
@ -1,315 +0,0 @@
|
||||
/* GNU linker script for ESP8266, common sections and symbols */
|
||||
|
||||
/* define the top of RAM */
|
||||
_heap_end = ORIGIN(dram0_0_seg) + LENGTH(dram0_0_seg);
|
||||
|
||||
PHDRS
|
||||
{
|
||||
dport0_0_phdr PT_LOAD;
|
||||
dram0_0_phdr PT_LOAD;
|
||||
dram0_0_bss_phdr PT_LOAD;
|
||||
iram1_0_phdr PT_LOAD;
|
||||
irom0_0_phdr PT_LOAD;
|
||||
}
|
||||
|
||||
ENTRY(firmware_start)
|
||||
EXTERN(_DebugExceptionVector)
|
||||
EXTERN(_DoubleExceptionVector)
|
||||
EXTERN(_KernelExceptionVector)
|
||||
EXTERN(_NMIExceptionVector)
|
||||
EXTERN(_UserExceptionVector)
|
||||
|
||||
_firmware_size = ORIGIN(irom0_0_seg) + LENGTH(irom0_0_seg) - 0x40200000;
|
||||
|
||||
PROVIDE(_memmap_vecbase_reset = 0x40000000);
|
||||
|
||||
/* Various memory-map dependent cache attribute settings: */
|
||||
_memmap_cacheattr_wb_base = 0x00000110;
|
||||
_memmap_cacheattr_wt_base = 0x00000110;
|
||||
_memmap_cacheattr_bp_base = 0x00000220;
|
||||
_memmap_cacheattr_unused_mask = 0xFFFFF00F;
|
||||
_memmap_cacheattr_wb_trapnull = 0x2222211F;
|
||||
_memmap_cacheattr_wba_trapnull = 0x2222211F;
|
||||
_memmap_cacheattr_wbna_trapnull = 0x2222211F;
|
||||
_memmap_cacheattr_wt_trapnull = 0x2222211F;
|
||||
_memmap_cacheattr_bp_trapnull = 0x2222222F;
|
||||
_memmap_cacheattr_wb_strict = 0xFFFFF11F;
|
||||
_memmap_cacheattr_wt_strict = 0xFFFFF11F;
|
||||
_memmap_cacheattr_bp_strict = 0xFFFFF22F;
|
||||
_memmap_cacheattr_wb_allvalid = 0x22222112;
|
||||
_memmap_cacheattr_wt_allvalid = 0x22222112;
|
||||
_memmap_cacheattr_bp_allvalid = 0x22222222;
|
||||
PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_wb_trapnull);
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
|
||||
.dport0.rodata : ALIGN(4)
|
||||
{
|
||||
_dport0_rodata_start = ABSOLUTE(.);
|
||||
*(.dport0.rodata)
|
||||
*(.dport.rodata)
|
||||
_dport0_rodata_end = ABSOLUTE(.);
|
||||
} >dport0_0_seg :dport0_0_phdr
|
||||
|
||||
.dport0.literal : ALIGN(4)
|
||||
{
|
||||
_dport0_literal_start = ABSOLUTE(.);
|
||||
*(.dport0.literal)
|
||||
*(.dport.literal)
|
||||
_dport0_literal_end = ABSOLUTE(.);
|
||||
} >dport0_0_seg :dport0_0_phdr
|
||||
|
||||
.dport0.data : ALIGN(4)
|
||||
{
|
||||
_dport0_data_start = ABSOLUTE(.);
|
||||
*(.dport0.data)
|
||||
*(.dport.data)
|
||||
_dport0_data_end = ABSOLUTE(.);
|
||||
} >dport0_0_seg :dport0_0_phdr
|
||||
|
||||
.irom0.text : ALIGN(4)
|
||||
{
|
||||
_irom0_text_start = ABSOLUTE(.);
|
||||
*(.irom0.literal .irom.literal .irom.text.literal .irom0.text .irom.text)
|
||||
|
||||
/* Vendor SDK in v2.1.0-7-gb8fd588 started to build these with
|
||||
-ffunction-sections -fdata-sections, and require routing to
|
||||
irom via linker:
|
||||
https://github.com/espressif/ESP8266_NONOS_SDK/commit/b8fd588a33f0319dc135523b51655e97b483b205
|
||||
*/
|
||||
|
||||
*libcrypto.a:(.literal.* .text.*)
|
||||
*libnet80211.a:(.literal.* .text.*)
|
||||
*libwpa.a:(.literal.* .text.*)
|
||||
*libwpa2.a:(.literal.* .text.*)
|
||||
|
||||
/* we put some specific text in this section */
|
||||
|
||||
*common-hal/*.o*(.literal* .text*)
|
||||
*shared-bindings/*.o*(.literal* .text*)
|
||||
*shared-module/*.o*(.literal* .text*)
|
||||
*supervisor/*.o*(.literal* .text*)
|
||||
|
||||
*py/argcheck.o*(.literal* .text*)
|
||||
*py/asm*.o*(.literal* .text*)
|
||||
*py/bc.o*(.literal* .text*)
|
||||
*py/binary.o*(.literal* .text*)
|
||||
*py/builtin*.o*(.literal* .text*)
|
||||
*py/compile.o*(.literal* .text*)
|
||||
*py/emit*.o*(.literal* .text*)
|
||||
*py/persistentcode*.o*(.literal* .text*)
|
||||
*py/formatfloat.o*(.literal* .text*)
|
||||
*py/frozenmod.o*(.literal* .text*)
|
||||
*py/gc.o*(.literal* .text*)
|
||||
*py/reader*.o*(.literal* .text*)
|
||||
*py/lexer*.o*(.literal* .text*)
|
||||
*py/malloc*.o*(.literal* .text*)
|
||||
*py/map*.o*(.literal* .text*)
|
||||
*py/mod*.o*(.literal* .text*)
|
||||
*py/mpprint.o*(.literal* .text*)
|
||||
*py/mpstate.o*(.literal* .text*)
|
||||
*py/mpz.o*(.literal* .text*)
|
||||
*py/native*.o*(.literal* .text*)
|
||||
*py/nlr*.o*(.literal* .text*)
|
||||
*py/obj*.o*(.literal* .text*)
|
||||
*py/opmethods.o*(.literal* .text*)
|
||||
*py/parse*.o*(.literal* .text*)
|
||||
*py/qstr.o*(.literal* .text*)
|
||||
*py/repl.o*(.literal* .text*)
|
||||
*py/runtime.o*(.literal* .text*)
|
||||
*py/scheduler.o*(.literal* .text*)
|
||||
*py/scope.o*(.literal* .text*)
|
||||
*py/sequence.o*(.literal* .text*)
|
||||
*py/showbc.o*(.literal* .text*)
|
||||
*py/smallint.o*(.literal* .text*)
|
||||
*py/stackctrl.o*(.literal* .text*)
|
||||
*py/stream.o*(.literal* .text*)
|
||||
*py/unicode.o*(.literal* .text*)
|
||||
*py/vm.o*(.literal* .text*)
|
||||
*py/vstr.o*(.literal* .text*)
|
||||
*py/warning.o*(.literal* .text*)
|
||||
|
||||
*extmod/*.o*(.literal* .text*)
|
||||
|
||||
*lib/oofatfs/*.o*(.literal*, .text*)
|
||||
*/libaxtls.a:(.literal*, .text*)
|
||||
*lib/berkeley-db-1.xx/*.o(.literal*, .text*)
|
||||
*lib/libm/*.o*(.literal*, .text*)
|
||||
*lib/mp-readline/*.o(.literal*, .text*)
|
||||
*lib/netutils/*.o*(.literal*, .text*)
|
||||
*lib/timeutils/*.o*(.literal*, .text*)
|
||||
*lib/utils/*.o*(.literal*, .text*)
|
||||
*drivers/bus/*.o(.literal* .text*)
|
||||
|
||||
build*/main.o(.literal* .text*)
|
||||
*gccollect.o(.literal* .text*)
|
||||
*gchelper.o(.literal* .text*)
|
||||
*help.o(.literal* .text*)
|
||||
*lexerstr32.o(.literal* .text*)
|
||||
*utils.o(.literal* .text*)
|
||||
*modpyb.o(.literal*, .text*)
|
||||
*machine_pin.o(.literal*, .text*)
|
||||
*machine_pwm.o(.literal*, .text*)
|
||||
*machine_rtc.o(.literal*, .text*)
|
||||
*machine_adc.o(.literal*, .text*)
|
||||
*machine_uart.o(.literal*, .text*)
|
||||
*modpybi2c.o(.literal*, .text*)
|
||||
*modmachine.o(.literal*, .text*)
|
||||
*machine_wdt.o(.literal*, .text*)
|
||||
*machine_spi.o(.literal*, .text*)
|
||||
*machine_hspi.o(.literal*, .text*)
|
||||
*hspi.o(.literal*, .text*)
|
||||
*modesp.o(.literal* .text*)
|
||||
*modnetwork.o(.literal* .text*)
|
||||
*moduos.o(.literal* .text*)
|
||||
*modutime.o(.literal* .text*)
|
||||
*modlwip.o(.literal* .text*)
|
||||
*modsocket.o(.literal* .text*)
|
||||
*modonewire.o(.literal* .text*)
|
||||
|
||||
/* we put as much rodata as possible in this section */
|
||||
/* note that only rodata accessed as a machine word is allowed here */
|
||||
*py/qstr.o(.rodata.const_pool)
|
||||
*.o(.rodata.mp_type_*) /* catches type: mp_obj_type_t */
|
||||
*.o(.rodata.*_locals_dict*) /* catches types: mp_obj_dict_t, mp_map_elem_t */
|
||||
*.o(.rodata.mp_module_*) /* catches types: mp_obj_module_t, mp_obj_dict_t, mp_map_elem_t */
|
||||
*/frozen.o(.rodata.mp_frozen_sizes) /* frozen modules */
|
||||
*/frozen.o(.rodata.mp_frozen_content) /* frozen modules */
|
||||
|
||||
/* for -mforce-l32 */
|
||||
build*/*.o(.rodata*)
|
||||
|
||||
_irom0_text_end = ABSOLUTE(.);
|
||||
} >irom0_0_seg :irom0_0_phdr
|
||||
|
||||
.text : ALIGN(4)
|
||||
{
|
||||
_stext = .;
|
||||
_text_start = ABSOLUTE(.);
|
||||
*(.UserEnter.text)
|
||||
. = ALIGN(16);
|
||||
*(.DebugExceptionVector.text)
|
||||
. = ALIGN(16);
|
||||
*(.NMIExceptionVector.text)
|
||||
. = ALIGN(16);
|
||||
*(.KernelExceptionVector.text)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
. = ALIGN(16);
|
||||
*(.UserExceptionVector.text)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
. = ALIGN(16);
|
||||
*(.DoubleExceptionVector.text)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
LONG(0)
|
||||
. = ALIGN (16);
|
||||
*(.entry.text)
|
||||
*(.init.literal)
|
||||
*(.init)
|
||||
*(.literal .text .literal.* .text.* .iram0.literal .iram0.text .iram0.text.*.literal .iram0.text.*)
|
||||
*(.stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
|
||||
*(.fini.literal)
|
||||
*(.fini)
|
||||
*(.gnu.version)
|
||||
_text_end = ABSOLUTE(.);
|
||||
_etext = .;
|
||||
} >iram1_0_seg :iram1_0_phdr
|
||||
|
||||
.lit4 : ALIGN(4)
|
||||
{
|
||||
_lit4_start = ABSOLUTE(.);
|
||||
*(*.lit4)
|
||||
*(.lit4.*)
|
||||
*(.gnu.linkonce.lit4.*)
|
||||
_lit4_end = ABSOLUTE(.);
|
||||
} >iram1_0_seg :iram1_0_phdr
|
||||
|
||||
.data : ALIGN(4)
|
||||
{
|
||||
_data_start = ABSOLUTE(.);
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.gnu.linkonce.d.*)
|
||||
*(.data1)
|
||||
*(.sdata)
|
||||
*(.sdata.*)
|
||||
*(.gnu.linkonce.s.*)
|
||||
*(.sdata2)
|
||||
*(.sdata2.*)
|
||||
*(.gnu.linkonce.s2.*)
|
||||
*(.jcr)
|
||||
_data_end = ABSOLUTE(.);
|
||||
} >dram0_0_seg :dram0_0_phdr
|
||||
|
||||
.rodata : ALIGN(4)
|
||||
{
|
||||
_rodata_start = ABSOLUTE(.);
|
||||
*(.sdk.version)
|
||||
*(.rodata)
|
||||
*(.rodata.*)
|
||||
*(.gnu.linkonce.r.*)
|
||||
*(.rodata1)
|
||||
__XT_EXCEPTION_TABLE__ = ABSOLUTE(.);
|
||||
*(.xt_except_table)
|
||||
*(.gcc_except_table)
|
||||
*(.gnu.linkonce.e.*)
|
||||
*(.gnu.version_r)
|
||||
*(.eh_frame)
|
||||
/* C++ constructor and destructor tables, properly ordered: */
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*(.ctors))
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*(.dtors))
|
||||
/* C++ exception handlers table: */
|
||||
__XT_EXCEPTION_DESCS__ = ABSOLUTE(.);
|
||||
*(.xt_except_desc)
|
||||
*(.gnu.linkonce.h.*)
|
||||
__XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
|
||||
*(.xt_except_desc_end)
|
||||
*(.dynamic)
|
||||
*(.gnu.version_d)
|
||||
. = ALIGN(4); /* this table MUST be 4-byte aligned */
|
||||
_bss_table_start = ABSOLUTE(.);
|
||||
LONG(_bss_start)
|
||||
LONG(_bss_end)
|
||||
_bss_table_end = ABSOLUTE(.);
|
||||
_rodata_end = ABSOLUTE(.);
|
||||
} >dram0_0_seg :dram0_0_phdr
|
||||
|
||||
.bss ALIGN(8) (NOLOAD) : ALIGN(4)
|
||||
{
|
||||
. = ALIGN (8);
|
||||
_bss_start = ABSOLUTE(.);
|
||||
*(.dynsbss)
|
||||
*(.sbss)
|
||||
*(.sbss.*)
|
||||
*(.gnu.linkonce.sb.*)
|
||||
*(.scommon)
|
||||
*(.sbss2)
|
||||
*(.sbss2.*)
|
||||
*(.gnu.linkonce.sb2.*)
|
||||
*(.dynbss)
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(.gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
. = ALIGN (8);
|
||||
_bss_end = ABSOLUTE(.);
|
||||
_heap_start = ABSOLUTE(.);
|
||||
} >dram0_0_seg :dram0_0_bss_phdr
|
||||
}
|
||||
|
||||
/* get ROM code address */
|
||||
INCLUDE "eagle.rom.addr.v6.ld"
|
@ -1,13 +0,0 @@
|
||||
/* GNU linker script for ESP8266 */
|
||||
|
||||
MEMORY
|
||||
{
|
||||
dport0_0_seg : org = 0x3ff00000, len = 0x10
|
||||
dram0_0_seg : org = 0x3ffe8000, len = 0x14000
|
||||
iram1_0_seg : org = 0x40100000, len = 0x8000
|
||||
/* 0x3c000 is size of bootloader, 0x9000 is size of packed RAM segments */
|
||||
irom0_0_seg : org = 0x40200000 + 0x3c000 + 0x9000, len = 0x8f000
|
||||
}
|
||||
|
||||
/* define common sections and symbols */
|
||||
INCLUDE esp8266_common.ld
|
@ -1,77 +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 <stdio.h>
|
||||
#include "ets_sys.h"
|
||||
#include "etshal.h"
|
||||
#include "esp_mphal.h"
|
||||
#include "user_interface.h"
|
||||
#include "extmod/misc.h"
|
||||
|
||||
NORETURN void call_user_start(void);
|
||||
void ets_printf(const char *fmt, ...);
|
||||
extern char flashchip;
|
||||
|
||||
static const uint8_t default_init_data[] __attribute__((aligned(4))) = {
|
||||
0x05, 0x00, 0x04, 0x02, 0x05, 0x05, 0x05, 0x02, 0x05, 0x00, 0x04, 0x05, 0x05, 0x04, 0x05, 0x05,
|
||||
0x04, 0xfe, 0xfd, 0xff, 0xf0, 0xf0, 0xf0, 0xe0, 0xe0, 0xe0, 0xe1, 0x0a, 0xff, 0xff, 0xf8, 0x00,
|
||||
0xf8, 0xf8, 0x52, 0x4e, 0x4a, 0x44, 0x40, 0x38, 0x00, 0x00, 0x01, 0x01, 0x02, 0x03, 0x04, 0x05,
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xe1, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x93, 0x43, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
void firmware_start(void) {
|
||||
// For SDK 1.5.2, either address has shifted and not mirrored in
|
||||
// eagle.rom.addr.v6.ld, or extra initial member was added.
|
||||
SpiFlashChip *flash = (SpiFlashChip*)(&flashchip + 4);
|
||||
|
||||
char buf[128];
|
||||
SPIRead(flash->chip_size - 4 * 0x1000, buf, sizeof(buf));
|
||||
/*for (int i = 0; i < sizeof(buf); i++) {
|
||||
static char hexf[] = "%x ";
|
||||
ets_printf(hexf, buf[i]);
|
||||
}*/
|
||||
|
||||
bool inited = false;
|
||||
for (int i = 0; i < sizeof(buf); i++) {
|
||||
if (buf[i] != 0xff) {
|
||||
inited = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!inited) {
|
||||
static char msg[] = "Writing init data\n";
|
||||
ets_printf(msg);
|
||||
SPIRead((uint32_t)&default_init_data - 0x40200000, buf, sizeof(buf));
|
||||
SPIWrite(flash->chip_size - 4 * 0x1000, buf, sizeof(buf));
|
||||
}
|
||||
|
||||
asm("j call_user_start");
|
||||
}
|
@ -1,215 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014 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 "ets_sys.h"
|
||||
#include "etshal.h"
|
||||
#include "uart.h"
|
||||
#include "esp_mphal.h"
|
||||
#include "user_interface.h"
|
||||
#include "ets_alt_task.h"
|
||||
#include "py/runtime.h"
|
||||
#include "extmod/misc.h"
|
||||
#include "lib/utils/pyexec.h"
|
||||
#include "supervisor/shared/translate.h"
|
||||
|
||||
STATIC byte input_buf_array[256];
|
||||
ringbuf_t stdin_ringbuf = {input_buf_array, sizeof(input_buf_array)};
|
||||
void mp_hal_debug_tx_strn_cooked(void *env, const char *str, uint32_t len);
|
||||
const mp_print_t mp_debug_print = {NULL, mp_hal_debug_tx_strn_cooked};
|
||||
|
||||
void mp_hal_init(void) {
|
||||
//ets_wdt_disable(); // it's a pain while developing
|
||||
mp_hal_rtc_init();
|
||||
uart_init(UART_BIT_RATE_115200, UART_BIT_RATE_115200);
|
||||
}
|
||||
|
||||
void mp_hal_delay_us(uint32_t us) {
|
||||
uint32_t start = system_get_time();
|
||||
while (system_get_time() - start < us) {
|
||||
ets_event_poll();
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t mp_hal_get_cpu_freq(void) {
|
||||
return system_get_cpu_freq() * 1000000;
|
||||
}
|
||||
|
||||
int mp_hal_stdin_rx_chr(void) {
|
||||
for (;;) {
|
||||
int c = ringbuf_get(&stdin_ringbuf);
|
||||
if (c != -1) {
|
||||
return c;
|
||||
}
|
||||
#if 0
|
||||
// Idles CPU but need more testing before enabling
|
||||
if (!ets_loop_iter()) {
|
||||
asm("waiti 0");
|
||||
}
|
||||
#else
|
||||
mp_hal_delay_us(1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
void mp_hal_debug_str(const char *str) {
|
||||
while (*str) {
|
||||
uart_tx_one_char(UART0, *str++);
|
||||
}
|
||||
uart_flush(UART0);
|
||||
}
|
||||
#endif
|
||||
|
||||
void mp_hal_stdout_tx_str(const char *str) {
|
||||
const char *last = str;
|
||||
while (*str) {
|
||||
uart_tx_one_char(UART0, *str++);
|
||||
}
|
||||
mp_uos_dupterm_tx_strn(last, str - last);
|
||||
}
|
||||
|
||||
void mp_hal_stdout_tx_strn(const char *str, uint32_t len) {
|
||||
const char *last = str;
|
||||
while (len--) {
|
||||
uart_tx_one_char(UART0, *str++);
|
||||
}
|
||||
mp_uos_dupterm_tx_strn(last, str - last);
|
||||
}
|
||||
|
||||
void mp_hal_stdout_tx_strn_cooked(const char *str, uint32_t len) {
|
||||
const char *last = str;
|
||||
while (len--) {
|
||||
if (*str == '\n') {
|
||||
if (str > last) {
|
||||
mp_uos_dupterm_tx_strn(last, str - last);
|
||||
}
|
||||
uart_tx_one_char(UART0, '\r');
|
||||
uart_tx_one_char(UART0, '\n');
|
||||
mp_uos_dupterm_tx_strn("\r\n", 2);
|
||||
++str;
|
||||
last = str;
|
||||
} else {
|
||||
uart_tx_one_char(UART0, *str++);
|
||||
}
|
||||
}
|
||||
if (str > last) {
|
||||
mp_uos_dupterm_tx_strn(last, str - last);
|
||||
}
|
||||
}
|
||||
|
||||
void mp_hal_debug_tx_strn_cooked(void *env, const char *str, uint32_t len) {
|
||||
(void)env;
|
||||
while (len--) {
|
||||
if (*str == '\n') {
|
||||
uart_tx_one_char(UART0, '\r');
|
||||
}
|
||||
uart_tx_one_char(UART0, *str++);
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t mp_hal_ticks_ms(void) {
|
||||
return ((uint64_t)system_time_high_word << 32 | (uint64_t)system_get_time()) / 1000;
|
||||
}
|
||||
|
||||
uint32_t mp_hal_ticks_us(void) {
|
||||
return system_get_time();
|
||||
}
|
||||
|
||||
void mp_hal_delay_ms(uint32_t delay) {
|
||||
mp_hal_delay_us(delay * 1000);
|
||||
}
|
||||
|
||||
void ets_event_poll(void) {
|
||||
ets_loop_iter();
|
||||
mp_handle_pending();
|
||||
}
|
||||
|
||||
void __assert_func(const char *file, int line, const char *func, const char *expr) {
|
||||
printf("assert:%s:%d:%s: %s\n", file, line, func, expr);
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_AssertionError,
|
||||
translate("C-level assert")));
|
||||
}
|
||||
|
||||
void mp_hal_signal_input(void) {
|
||||
#if MICROPY_REPL_EVENT_DRIVEN
|
||||
system_os_post(UART_TASK_ID, 0, 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
STATIC void dupterm_task_handler(os_event_t *evt) {
|
||||
static byte lock;
|
||||
if (lock) {
|
||||
return;
|
||||
}
|
||||
lock = 1;
|
||||
while (1) {
|
||||
int c = mp_uos_dupterm_rx_chr();
|
||||
if (c < 0) {
|
||||
break;
|
||||
}
|
||||
ringbuf_put(&stdin_ringbuf, c);
|
||||
}
|
||||
mp_hal_signal_input();
|
||||
lock = 0;
|
||||
}
|
||||
|
||||
STATIC os_event_t dupterm_evt_queue[4];
|
||||
|
||||
void dupterm_task_init() {
|
||||
system_os_task(dupterm_task_handler, DUPTERM_TASK_ID, dupterm_evt_queue, MP_ARRAY_SIZE(dupterm_evt_queue));
|
||||
}
|
||||
|
||||
void mp_hal_signal_dupterm_input(void) {
|
||||
system_os_post(DUPTERM_TASK_ID, 0, 0);
|
||||
}
|
||||
|
||||
// Get pointer to esf_buf bookkeeping structure
|
||||
void *ets_get_esf_buf_ctlblk(void) {
|
||||
// Get literal ptr before start of esf_rx_buf_alloc func
|
||||
extern void *esf_rx_buf_alloc();
|
||||
return ((void**)esf_rx_buf_alloc)[-1];
|
||||
}
|
||||
|
||||
// Get number of esf_buf free buffers of given type, as encoded by index
|
||||
// idx 0 corresponds to buf types 1, 2; 1 - 4; 2 - 5; 3 - 7; 4 - 8
|
||||
// Only following buf types appear to be used:
|
||||
// 1 - tx buffer, 5 - management frame tx buffer; 8 - rx buffer
|
||||
int ets_esf_free_bufs(int idx) {
|
||||
uint32_t *p = ets_get_esf_buf_ctlblk();
|
||||
uint32_t *b = (uint32_t*)p[idx];
|
||||
int cnt = 0;
|
||||
while (b) {
|
||||
b = (uint32_t*)b[0x20 / 4];
|
||||
cnt++;
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
extern int mp_stream_errno;
|
||||
int *__errno() {
|
||||
return &mp_stream_errno;
|
||||
}
|
@ -1,95 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014 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 "py/ringbuf.h"
|
||||
#include "lib/utils/interrupt_char.h"
|
||||
#include "xtirq.h"
|
||||
|
||||
void mp_keyboard_interrupt(void);
|
||||
|
||||
struct _mp_print_t;
|
||||
// Structure for UART-only output via mp_printf()
|
||||
extern const struct _mp_print_t mp_debug_print;
|
||||
|
||||
extern ringbuf_t stdin_ringbuf;
|
||||
// Call this after putting data to stdin_ringbuf
|
||||
void mp_hal_signal_input(void);
|
||||
// Call this when data is available in dupterm object
|
||||
void mp_hal_signal_dupterm_input(void);
|
||||
|
||||
void mp_hal_init(void);
|
||||
void mp_hal_rtc_init(void);
|
||||
|
||||
uint32_t mp_hal_ticks_us(void);
|
||||
__attribute__((always_inline)) static inline uint32_t mp_hal_ticks_cpu(void) {
|
||||
uint32_t ccount;
|
||||
__asm__ __volatile__("rsr %0,ccount":"=a" (ccount));
|
||||
return ccount;
|
||||
}
|
||||
|
||||
void mp_hal_delay_us(uint32_t);
|
||||
void mp_hal_set_interrupt_char(int c);
|
||||
uint32_t mp_hal_get_cpu_freq(void);
|
||||
|
||||
#define UART_TASK_ID 0
|
||||
#define DUPTERM_TASK_ID 1
|
||||
void uart_task_init();
|
||||
void dupterm_task_init();
|
||||
|
||||
void ets_event_poll(void);
|
||||
#define ETS_POLL_WHILE(cond) { while (cond) ets_event_poll(); }
|
||||
|
||||
// needed for machine.I2C
|
||||
#include "osapi.h"
|
||||
#define mp_hal_delay_us_fast(us) os_delay_us(us)
|
||||
|
||||
#define mp_hal_quiet_timing_enter() disable_irq()
|
||||
#define mp_hal_quiet_timing_exit(irq_state) enable_irq(irq_state)
|
||||
|
||||
// C-level pin HAL
|
||||
#include "etshal.h"
|
||||
#include "gpio.h"
|
||||
#include "modmachine.h"
|
||||
#define MP_HAL_PIN_FMT "%u"
|
||||
#define mp_hal_pin_obj_t uint32_t
|
||||
#define mp_hal_get_pin_obj(o) mp_obj_get_pin(o)
|
||||
#define mp_hal_pin_name(p) (p)
|
||||
void mp_hal_pin_input(mp_hal_pin_obj_t pin);
|
||||
void mp_hal_pin_output(mp_hal_pin_obj_t pin);
|
||||
void mp_hal_pin_open_drain(mp_hal_pin_obj_t pin);
|
||||
#define mp_hal_pin_od_low(p) do { \
|
||||
if ((p) == 16) { WRITE_PERI_REG(RTC_GPIO_ENABLE, (READ_PERI_REG(RTC_GPIO_ENABLE) & ~1) | 1); } \
|
||||
else { gpio_output_set(0, 1 << (p), 1 << (p), 0); } \
|
||||
} while (0)
|
||||
#define mp_hal_pin_od_high(p) do { \
|
||||
if ((p) == 16) { WRITE_PERI_REG(RTC_GPIO_ENABLE, (READ_PERI_REG(RTC_GPIO_ENABLE) & ~1)); } \
|
||||
else { gpio_output_set(0, 0, 0, 1 << (p)); /* set as input to avoid glitches */ } \
|
||||
} while (0)
|
||||
#define mp_hal_pin_read(p) pin_get(p)
|
||||
#define mp_hal_pin_write(p, v) pin_set((p), (v))
|
||||
|
||||
void *ets_get_esf_buf_ctlblk(void);
|
||||
int ets_esf_free_bufs(int idx);
|
@ -1,65 +0,0 @@
|
||||
// Original version from https://github.com/adafruit/Adafruit_NeoPixel
|
||||
// Modifications by dpgeorge to support auto-CPU-frequency detection
|
||||
|
||||
// This is a mash-up of the Due show() code + insights from Michael Miller's
|
||||
// ESP8266 work for the NeoPixelBus library: github.com/Makuna/NeoPixelBus
|
||||
// Needs to be a separate .c file to enforce ICACHE_RAM_ATTR execution.
|
||||
|
||||
#include "py/mpconfig.h"
|
||||
#if MICROPY_ESP8266_NEOPIXEL
|
||||
|
||||
#include "c_types.h"
|
||||
#include "eagle_soc.h"
|
||||
#include "user_interface.h"
|
||||
#include "espneopixel.h"
|
||||
#include "esp_mphal.h"
|
||||
|
||||
#define NEO_KHZ400 (1)
|
||||
|
||||
void /*ICACHE_RAM_ATTR*/ esp_neopixel_write(uint8_t pin, uint8_t *pixels, uint32_t numBytes, bool is800KHz) {
|
||||
|
||||
uint8_t *p, *end, pix, mask;
|
||||
uint32_t t, time0, time1, period, c, startTime, pinMask;
|
||||
|
||||
pinMask = 1 << pin;
|
||||
p = pixels;
|
||||
end = p + numBytes;
|
||||
pix = *p++;
|
||||
mask = 0x80;
|
||||
startTime = 0;
|
||||
|
||||
uint32_t fcpu = system_get_cpu_freq() * 1000000;
|
||||
|
||||
#ifdef NEO_KHZ400
|
||||
if(is800KHz) {
|
||||
#endif
|
||||
time0 = fcpu / 2857143; // 0.35us
|
||||
time1 = fcpu / 1250000; // 0.8us
|
||||
period = fcpu / 800000; // 1.25us per bit
|
||||
#ifdef NEO_KHZ400
|
||||
} else { // 400 KHz bitstream
|
||||
time0 = fcpu / 2000000; // 0.5uS
|
||||
time1 = fcpu / 833333; // 1.2us
|
||||
period = fcpu / 400000; // 2.5us per bit
|
||||
}
|
||||
#endif
|
||||
|
||||
uint32_t irq_state = mp_hal_quiet_timing_enter();
|
||||
for(t = time0;; t = time0) {
|
||||
if(pix & mask) t = time1; // Bit high duration
|
||||
while(((c = mp_hal_ticks_cpu()) - startTime) < period); // Wait for bit start
|
||||
GPIO_REG_WRITE(GPIO_OUT_W1TS_ADDRESS, pinMask); // Set high
|
||||
startTime = c; // Save start time
|
||||
while(((c = mp_hal_ticks_cpu()) - startTime) < t); // Wait high duration
|
||||
GPIO_REG_WRITE(GPIO_OUT_W1TC_ADDRESS, pinMask); // Set low
|
||||
if(!(mask >>= 1)) { // Next bit/byte
|
||||
if(p >= end) break;
|
||||
pix = *p++;
|
||||
mask = 0x80;
|
||||
}
|
||||
}
|
||||
while((mp_hal_ticks_cpu() - startTime) < period); // Wait for last bit
|
||||
mp_hal_quiet_timing_exit(irq_state);
|
||||
}
|
||||
|
||||
#endif // MICROPY_ESP8266_NEOPIXEL
|
@ -1,6 +0,0 @@
|
||||
#ifndef MICROPY_INCLUDED_ESP8266_ESPNEOPIXEL_H
|
||||
#define MICROPY_INCLUDED_ESP8266_ESPNEOPIXEL_H
|
||||
|
||||
void esp_neopixel_write(uint8_t pin, uint8_t *pixels, uint32_t numBytes, bool is800KHz);
|
||||
|
||||
#endif // MICROPY_INCLUDED_ESP8266_ESPNEOPIXEL_H
|
@ -1,421 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Copyright 2013-2014 Espressif Systems (Wuxi)
|
||||
*
|
||||
* FileName: pwm.c
|
||||
*
|
||||
* Description: pwm driver
|
||||
*
|
||||
* Modification history:
|
||||
* 2014/5/1, v1.0 create this file.
|
||||
* 2016/3/2: Modifications by dpgeorge to suit MicroPython
|
||||
*******************************************************************************/
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "etshal.h"
|
||||
#include "os_type.h"
|
||||
#include "gpio.h"
|
||||
|
||||
#include "esppwm.h"
|
||||
|
||||
#include "py/mpprint.h"
|
||||
#define PWM_DBG(...)
|
||||
//#define PWM_DBG(...) mp_printf(&mp_plat_print, __VA_ARGS__)
|
||||
|
||||
#define ICACHE_RAM_ATTR // __attribute__((section(".text")))
|
||||
|
||||
#define PWM_CHANNEL 8
|
||||
#define PWM_DEPTH 1023
|
||||
#define PWM_FREQ_MAX 1000
|
||||
#define PWM_1S 1000000
|
||||
|
||||
struct pwm_single_param {
|
||||
uint16_t gpio_set;
|
||||
uint16_t gpio_clear;
|
||||
uint32_t h_time;
|
||||
};
|
||||
|
||||
struct pwm_param {
|
||||
uint32_t period;
|
||||
uint16_t freq;
|
||||
uint16_t duty[PWM_CHANNEL];
|
||||
};
|
||||
|
||||
STATIC const uint8_t pin_num[PWM_CHANNEL] = {0, 2, 4, 5, 12, 13, 14, 15};
|
||||
|
||||
STATIC struct pwm_single_param pwm_single_toggle[2][PWM_CHANNEL + 1];
|
||||
STATIC struct pwm_single_param *pwm_single;
|
||||
|
||||
STATIC struct pwm_param pwm;
|
||||
|
||||
STATIC int8_t pwm_out_io_num[PWM_CHANNEL] = {-1, -1, -1, -1, -1, -1, -1, -1};
|
||||
|
||||
STATIC uint8_t pwm_channel_toggle[2];
|
||||
STATIC uint8_t *pwm_channel;
|
||||
STATIC uint8_t pwm_toggle = 1;
|
||||
STATIC uint8_t pwm_timer_down = 1;
|
||||
STATIC uint8_t pwm_current_channel = 0;
|
||||
STATIC uint16_t pwm_gpio = 0;
|
||||
STATIC uint8_t pwm_channel_num = 0;
|
||||
|
||||
//XXX: 0xffffffff/(80000000/16)=35A
|
||||
#define US_TO_RTC_TIMER_TICKS(t) \
|
||||
((t) ? \
|
||||
(((t) > 0x35A) ? \
|
||||
(((t)>>2) * ((APB_CLK_FREQ>>4)/250000) + ((t)&0x3) * ((APB_CLK_FREQ>>4)/1000000)) : \
|
||||
(((t) *(APB_CLK_FREQ>>4)) / 1000000)) : \
|
||||
0)
|
||||
|
||||
//FRC1
|
||||
#define FRC1_ENABLE_TIMER BIT7
|
||||
|
||||
typedef enum {
|
||||
DIVDED_BY_1 = 0,
|
||||
DIVDED_BY_16 = 4,
|
||||
DIVDED_BY_256 = 8,
|
||||
} TIMER_PREDIVED_MODE;
|
||||
|
||||
typedef enum {
|
||||
TM_LEVEL_INT = 1,
|
||||
TM_EDGE_INT = 0,
|
||||
} TIMER_INT_MODE;
|
||||
|
||||
STATIC void ICACHE_FLASH_ATTR
|
||||
pwm_insert_sort(struct pwm_single_param pwm[], uint8 n)
|
||||
{
|
||||
uint8 i;
|
||||
|
||||
for (i = 1; i < n; i++) {
|
||||
if (pwm[i].h_time < pwm[i - 1].h_time) {
|
||||
int8 j = i - 1;
|
||||
struct pwm_single_param tmp;
|
||||
|
||||
memcpy(&tmp, &pwm[i], sizeof(struct pwm_single_param));
|
||||
memcpy(&pwm[i], &pwm[i - 1], sizeof(struct pwm_single_param));
|
||||
|
||||
while (tmp.h_time < pwm[j].h_time) {
|
||||
memcpy(&pwm[j + 1], &pwm[j], sizeof(struct pwm_single_param));
|
||||
j--;
|
||||
if (j < 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
memcpy(&pwm[j + 1], &tmp, sizeof(struct pwm_single_param));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STATIC volatile uint8 critical = 0;
|
||||
|
||||
#define LOCK_PWM(c) do { \
|
||||
while( (c)==1 ); \
|
||||
(c) = 1; \
|
||||
} while (0)
|
||||
|
||||
#define UNLOCK_PWM(c) do { \
|
||||
(c) = 0; \
|
||||
} while (0)
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
pwm_start(void)
|
||||
{
|
||||
uint8 i, j;
|
||||
PWM_DBG("--Function pwm_start() is called\n");
|
||||
PWM_DBG("pwm_gpio:%x,pwm_channel_num:%d\n",pwm_gpio,pwm_channel_num);
|
||||
PWM_DBG("pwm_out_io_num[0]:%d,[1]:%d,[2]:%d\n",pwm_out_io_num[0],pwm_out_io_num[1],pwm_out_io_num[2]);
|
||||
PWM_DBG("pwm.period:%d,pwm.duty[0]:%d,[1]:%d,[2]:%d\n",pwm.period,pwm.duty[0],pwm.duty[1],pwm.duty[2]);
|
||||
|
||||
LOCK_PWM(critical); // enter critical
|
||||
|
||||
struct pwm_single_param *local_single = pwm_single_toggle[pwm_toggle ^ 0x01];
|
||||
uint8 *local_channel = &pwm_channel_toggle[pwm_toggle ^ 0x01];
|
||||
|
||||
// step 1: init PWM_CHANNEL+1 channels param
|
||||
for (i = 0; i < pwm_channel_num; i++) {
|
||||
uint32 us = pwm.period * pwm.duty[i] / PWM_DEPTH;
|
||||
local_single[i].h_time = US_TO_RTC_TIMER_TICKS(us);
|
||||
PWM_DBG("i:%d us:%d ht:%d\n",i,us,local_single[i].h_time);
|
||||
local_single[i].gpio_set = 0;
|
||||
local_single[i].gpio_clear = 1 << pin_num[pwm_out_io_num[i]];
|
||||
}
|
||||
|
||||
local_single[pwm_channel_num].h_time = US_TO_RTC_TIMER_TICKS(pwm.period);
|
||||
local_single[pwm_channel_num].gpio_set = pwm_gpio;
|
||||
local_single[pwm_channel_num].gpio_clear = 0;
|
||||
PWM_DBG("i:%d period:%d ht:%d\n",pwm_channel_num,pwm.period,local_single[pwm_channel_num].h_time);
|
||||
// step 2: sort, small to big
|
||||
pwm_insert_sort(local_single, pwm_channel_num + 1);
|
||||
|
||||
*local_channel = pwm_channel_num + 1;
|
||||
PWM_DBG("1channel:%d,single[0]:%d,[1]:%d,[2]:%d,[3]:%d\n",*local_channel,local_single[0].h_time,local_single[1].h_time,local_single[2].h_time,local_single[3].h_time);
|
||||
// step 3: combine same duty channels
|
||||
for (i = pwm_channel_num; i > 0; i--) {
|
||||
if (local_single[i].h_time == local_single[i - 1].h_time) {
|
||||
local_single[i - 1].gpio_set |= local_single[i].gpio_set;
|
||||
local_single[i - 1].gpio_clear |= local_single[i].gpio_clear;
|
||||
|
||||
for (j = i + 1; j < *local_channel; j++) {
|
||||
memcpy(&local_single[j - 1], &local_single[j], sizeof(struct pwm_single_param));
|
||||
}
|
||||
|
||||
(*local_channel)--;
|
||||
}
|
||||
}
|
||||
PWM_DBG("2channel:%d,single[0]:%d,[1]:%d,[2]:%d,[3]:%d\n",*local_channel,local_single[0].h_time,local_single[1].h_time,local_single[2].h_time,local_single[3].h_time);
|
||||
// step 4: cacl delt time
|
||||
for (i = *local_channel - 1; i > 0; i--) {
|
||||
local_single[i].h_time -= local_single[i - 1].h_time;
|
||||
}
|
||||
|
||||
// step 5: last channel needs to clean
|
||||
local_single[*local_channel-1].gpio_clear = 0;
|
||||
|
||||
// step 6: if first channel duty is 0, remove it
|
||||
if (local_single[0].h_time == 0) {
|
||||
local_single[*local_channel - 1].gpio_set &= ~local_single[0].gpio_clear;
|
||||
local_single[*local_channel - 1].gpio_clear |= local_single[0].gpio_clear;
|
||||
|
||||
for (i = 1; i < *local_channel; i++) {
|
||||
memcpy(&local_single[i - 1], &local_single[i], sizeof(struct pwm_single_param));
|
||||
}
|
||||
|
||||
(*local_channel)--;
|
||||
}
|
||||
|
||||
// if timer is down, need to set gpio and start timer
|
||||
if (pwm_timer_down == 1) {
|
||||
pwm_channel = local_channel;
|
||||
pwm_single = local_single;
|
||||
// start
|
||||
gpio_output_set(local_single[0].gpio_set, local_single[0].gpio_clear, pwm_gpio, 0);
|
||||
|
||||
pwm_timer_down = 0;
|
||||
RTC_REG_WRITE(FRC1_LOAD_ADDRESS, local_single[0].h_time);
|
||||
}
|
||||
|
||||
if (pwm_toggle == 1) {
|
||||
pwm_toggle = 0;
|
||||
} else {
|
||||
pwm_toggle = 1;
|
||||
}
|
||||
|
||||
UNLOCK_PWM(critical); // leave critical
|
||||
PWM_DBG("3channel:%d,single[0]:%d,[1]:%d,[2]:%d,[3]:%d\n",*local_channel,local_single[0].h_time,local_single[1].h_time,local_single[2].h_time,local_single[3].h_time);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : pwm_set_duty
|
||||
* Description : set each channel's duty params
|
||||
* Parameters : int16_t duty : 0 ~ PWM_DEPTH
|
||||
* uint8 channel : channel index
|
||||
* Returns : NONE
|
||||
*******************************************************************************/
|
||||
void ICACHE_FLASH_ATTR
|
||||
pwm_set_duty(int16_t duty, uint8 channel)
|
||||
{
|
||||
uint8 i;
|
||||
for(i=0;i<pwm_channel_num;i++){
|
||||
if(pwm_out_io_num[i] == channel){
|
||||
channel = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(i==pwm_channel_num) // non found
|
||||
return;
|
||||
|
||||
LOCK_PWM(critical); // enter critical
|
||||
if (duty < 1) {
|
||||
pwm.duty[channel] = 0;
|
||||
} else if (duty >= PWM_DEPTH) {
|
||||
pwm.duty[channel] = PWM_DEPTH;
|
||||
} else {
|
||||
pwm.duty[channel] = duty;
|
||||
}
|
||||
UNLOCK_PWM(critical); // leave critical
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : pwm_set_freq
|
||||
* Description : set pwm frequency
|
||||
* Parameters : uint16 freq : 100hz typically
|
||||
* Returns : NONE
|
||||
*******************************************************************************/
|
||||
void ICACHE_FLASH_ATTR
|
||||
pwm_set_freq(uint16 freq, uint8 channel)
|
||||
{
|
||||
LOCK_PWM(critical); // enter critical
|
||||
if (freq > PWM_FREQ_MAX) {
|
||||
pwm.freq = PWM_FREQ_MAX;
|
||||
} else if (freq < 1) {
|
||||
pwm.freq = 1;
|
||||
} else {
|
||||
pwm.freq = freq;
|
||||
}
|
||||
|
||||
pwm.period = PWM_1S / pwm.freq;
|
||||
UNLOCK_PWM(critical); // leave critical
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : pwm_get_duty
|
||||
* Description : get duty of each channel
|
||||
* Parameters : uint8 channel : channel index
|
||||
* Returns : NONE
|
||||
*******************************************************************************/
|
||||
uint16 ICACHE_FLASH_ATTR
|
||||
pwm_get_duty(uint8 channel)
|
||||
{
|
||||
uint8 i;
|
||||
for(i=0;i<pwm_channel_num;i++){
|
||||
if(pwm_out_io_num[i] == channel){
|
||||
channel = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(i==pwm_channel_num) // non found
|
||||
return 0;
|
||||
|
||||
return pwm.duty[channel];
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : pwm_get_freq
|
||||
* Description : get pwm frequency
|
||||
* Parameters : NONE
|
||||
* Returns : uint16 : pwm frequency
|
||||
*******************************************************************************/
|
||||
uint16 ICACHE_FLASH_ATTR
|
||||
pwm_get_freq(uint8 channel)
|
||||
{
|
||||
return pwm.freq;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : pwm_period_timer
|
||||
* Description : pwm period timer function, output high level,
|
||||
* start each channel's high level timer
|
||||
* Parameters : NONE
|
||||
* Returns : NONE
|
||||
*******************************************************************************/
|
||||
STATIC void ICACHE_RAM_ATTR
|
||||
pwm_tim1_intr_handler(void *dummy)
|
||||
{
|
||||
(void)dummy;
|
||||
uint8 local_toggle = pwm_toggle; // pwm_toggle may change outside
|
||||
RTC_CLR_REG_MASK(FRC1_INT_ADDRESS, FRC1_INT_CLR_MASK);
|
||||
|
||||
if (pwm_current_channel >= (*pwm_channel - 1)) { // *pwm_channel may change outside
|
||||
pwm_single = pwm_single_toggle[local_toggle];
|
||||
pwm_channel = &pwm_channel_toggle[local_toggle];
|
||||
|
||||
gpio_output_set(pwm_single[*pwm_channel - 1].gpio_set,
|
||||
pwm_single[*pwm_channel - 1].gpio_clear,
|
||||
pwm_gpio,
|
||||
0);
|
||||
|
||||
pwm_current_channel = 0;
|
||||
|
||||
RTC_REG_WRITE(FRC1_LOAD_ADDRESS, pwm_single[pwm_current_channel].h_time);
|
||||
} else {
|
||||
gpio_output_set(pwm_single[pwm_current_channel].gpio_set,
|
||||
pwm_single[pwm_current_channel].gpio_clear,
|
||||
pwm_gpio, 0);
|
||||
|
||||
pwm_current_channel++;
|
||||
RTC_REG_WRITE(FRC1_LOAD_ADDRESS, pwm_single[pwm_current_channel].h_time);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : pwm_init
|
||||
* Description : pwm gpio, params and timer initialization
|
||||
* Parameters : uint16 freq : pwm freq param
|
||||
* uint16 *duty : each channel's duty
|
||||
* Returns : NONE
|
||||
*******************************************************************************/
|
||||
void ICACHE_FLASH_ATTR
|
||||
pwm_init(void)
|
||||
{
|
||||
uint8 i;
|
||||
|
||||
RTC_REG_WRITE(FRC1_CTRL_ADDRESS, //FRC2_AUTO_RELOAD|
|
||||
DIVDED_BY_16
|
||||
| FRC1_ENABLE_TIMER
|
||||
| TM_EDGE_INT);
|
||||
RTC_REG_WRITE(FRC1_LOAD_ADDRESS, 0);
|
||||
|
||||
for (i = 0; i < PWM_CHANNEL; i++) {
|
||||
pwm_gpio = 0;
|
||||
pwm.duty[i] = 0;
|
||||
}
|
||||
|
||||
pwm_set_freq(500, 0);
|
||||
pwm_start();
|
||||
|
||||
ETS_FRC_TIMER1_INTR_ATTACH(pwm_tim1_intr_handler, NULL);
|
||||
TM1_EDGE_INT_ENABLE();
|
||||
ETS_FRC1_INTR_ENABLE();
|
||||
}
|
||||
|
||||
int ICACHE_FLASH_ATTR
|
||||
pwm_add(uint8_t pin_id, uint32_t pin_mux, uint32_t pin_func){
|
||||
PWM_DBG("--Function pwm_add() is called. channel:%d\n", channel);
|
||||
PWM_DBG("pwm_gpio:%x,pwm_channel_num:%d\n",pwm_gpio,pwm_channel_num);
|
||||
PWM_DBG("pwm_out_io_num[0]:%d,[1]:%d,[2]:%d\n",pwm_out_io_num[0],pwm_out_io_num[1],pwm_out_io_num[2]);
|
||||
PWM_DBG("pwm.duty[0]:%d,[1]:%d,[2]:%d\n",pwm.duty[0],pwm.duty[1],pwm.duty[2]);
|
||||
int channel = -1;
|
||||
for (int i = 0; i < PWM_CHANNEL; ++i) {
|
||||
if (pin_num[i] == pin_id) {
|
||||
channel = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (channel == -1) {
|
||||
return -1;
|
||||
}
|
||||
uint8 i;
|
||||
for(i=0;i<PWM_CHANNEL;i++){
|
||||
if(pwm_out_io_num[i]==channel) // already exist
|
||||
return channel;
|
||||
if(pwm_out_io_num[i] == -1){ // empty exist
|
||||
LOCK_PWM(critical); // enter critical
|
||||
pwm_out_io_num[i] = channel;
|
||||
pwm.duty[i] = 0;
|
||||
pwm_gpio |= (1 << pin_num[channel]);
|
||||
PIN_FUNC_SELECT(pin_mux, pin_func);
|
||||
GPIO_REG_WRITE(GPIO_PIN_ADDR(GPIO_ID_PIN(pin_num[channel])), GPIO_REG_READ(GPIO_PIN_ADDR(GPIO_ID_PIN(pin_num[channel]))) & (~ GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_ENABLE))); //disable open drain;
|
||||
pwm_channel_num++;
|
||||
UNLOCK_PWM(critical); // leave critical
|
||||
return channel;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool ICACHE_FLASH_ATTR
|
||||
pwm_delete(uint8 channel){
|
||||
PWM_DBG("--Function pwm_delete() is called. channel:%d\n", channel);
|
||||
PWM_DBG("pwm_gpio:%x,pwm_channel_num:%d\n",pwm_gpio,pwm_channel_num);
|
||||
PWM_DBG("pwm_out_io_num[0]:%d,[1]:%d,[2]:%d\n",pwm_out_io_num[0],pwm_out_io_num[1],pwm_out_io_num[2]);
|
||||
PWM_DBG("pwm.duty[0]:%d,[1]:%d,[2]:%d\n",pwm.duty[0],pwm.duty[1],pwm.duty[2]);
|
||||
uint8 i,j;
|
||||
for(i=0;i<pwm_channel_num;i++){
|
||||
if(pwm_out_io_num[i]==channel){ // exist
|
||||
LOCK_PWM(critical); // enter critical
|
||||
pwm_out_io_num[i] = -1;
|
||||
pwm_gpio &= ~(1 << pin_num[channel]); //clear the bit
|
||||
for(j=i;j<pwm_channel_num-1;j++){
|
||||
pwm_out_io_num[j] = pwm_out_io_num[j+1];
|
||||
pwm.duty[j] = pwm.duty[j+1];
|
||||
}
|
||||
pwm_out_io_num[pwm_channel_num-1] = -1;
|
||||
pwm.duty[pwm_channel_num-1] = 0;
|
||||
pwm_channel_num--;
|
||||
UNLOCK_PWM(critical); // leave critical
|
||||
return true;
|
||||
}
|
||||
}
|
||||
// non found
|
||||
return true;
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
#ifndef MICROPY_INCLUDED_ESP8266_ESPPWM_H
|
||||
#define MICROPY_INCLUDED_ESP8266_ESPPWM_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void pwm_init(void);
|
||||
void pwm_start(void);
|
||||
|
||||
void pwm_set_duty(int16_t duty, uint8_t channel);
|
||||
uint16_t pwm_get_duty(uint8_t channel);
|
||||
void pwm_set_freq(uint16_t freq, uint8_t channel);
|
||||
uint16_t pwm_get_freq(uint8_t channel);
|
||||
int pwm_add(uint8_t pin_id, uint32_t pin_mux, uint32_t pin_func);
|
||||
bool pwm_delete(uint8_t channel);
|
||||
|
||||
#endif // MICROPY_INCLUDED_ESP8266_ESPPWM_H
|
@ -1,214 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include "osapi.h"
|
||||
#include "os_type.h"
|
||||
#include "ets_sys.h"
|
||||
#include <esp_sdk_ver.h>
|
||||
#include "etshal.h"
|
||||
#include "user_interface.h"
|
||||
#include "ets_alt_task.h"
|
||||
|
||||
// Use standard ets_task or alternative impl
|
||||
#define USE_ETS_TASK 0
|
||||
|
||||
#define MP_ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||
|
||||
struct task_entry {
|
||||
os_event_t *queue;
|
||||
os_task_t task;
|
||||
uint8_t qlen;
|
||||
uint8_t prio;
|
||||
int8_t i_get;
|
||||
int8_t i_put;
|
||||
};
|
||||
|
||||
static void (*idle_cb)(void *);
|
||||
static void *idle_arg;
|
||||
|
||||
#if ESP_SDK_VERSION >= 010500
|
||||
# define FIRST_PRIO 0
|
||||
#else
|
||||
# define FIRST_PRIO 0x14
|
||||
#endif
|
||||
#define LAST_PRIO 0x20
|
||||
#define PRIO2ID(prio) ((prio) - FIRST_PRIO)
|
||||
|
||||
volatile struct task_entry emu_tasks[PRIO2ID(LAST_PRIO) + 1];
|
||||
|
||||
static inline int prio2id(uint8_t prio) {
|
||||
int id = PRIO2ID(prio);
|
||||
if (id < 0 || id >= MP_ARRAY_SIZE(emu_tasks)) {
|
||||
printf("task prio out of range: %d\n", prio);
|
||||
while (1);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
void dump_task(int prio, volatile struct task_entry *t) {
|
||||
printf("q for task %d: queue: %p, get ptr: %d, put ptr: %d, qlen: %d\n",
|
||||
prio, t->queue, t->i_get, t->i_put, t->qlen);
|
||||
}
|
||||
|
||||
void dump_tasks(void) {
|
||||
for (int i = 0; i < MP_ARRAY_SIZE(emu_tasks); i++) {
|
||||
if (emu_tasks[i].qlen) {
|
||||
dump_task(i + FIRST_PRIO, &emu_tasks[i]);
|
||||
}
|
||||
}
|
||||
printf("====\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
bool ets_task(os_task_t task, uint8 prio, os_event_t *queue, uint8 qlen) {
|
||||
static unsigned cnt;
|
||||
printf("#%d ets_task(%p, %d, %p, %d)\n", cnt++, task, prio, queue, qlen);
|
||||
#if USE_ETS_TASK
|
||||
return _ets_task(task, prio, queue, qlen);
|
||||
#else
|
||||
int id = prio2id(prio);
|
||||
emu_tasks[id].task = task;
|
||||
emu_tasks[id].queue = queue;
|
||||
emu_tasks[id].qlen = qlen;
|
||||
emu_tasks[id].i_get = 0;
|
||||
emu_tasks[id].i_put = 0;
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool ets_post(uint8 prio, os_signal_t sig, os_param_t param) {
|
||||
// static unsigned cnt; printf("#%d ets_post(%d, %x, %x)\n", cnt++, prio, sig, param);
|
||||
#if USE_ETS_TASK
|
||||
return _ets_post(prio, sig, param);
|
||||
#else
|
||||
ets_intr_lock();
|
||||
|
||||
const int id = prio2id(prio);
|
||||
os_event_t *q = emu_tasks[id].queue;
|
||||
if (emu_tasks[id].i_put == -1) {
|
||||
// queue is full
|
||||
printf("ets_post: task %d queue full\n", prio);
|
||||
return 1;
|
||||
}
|
||||
q = &q[emu_tasks[id].i_put++];
|
||||
q->sig = sig;
|
||||
q->par = param;
|
||||
if (emu_tasks[id].i_put == emu_tasks[id].qlen) {
|
||||
emu_tasks[id].i_put = 0;
|
||||
}
|
||||
if (emu_tasks[id].i_put == emu_tasks[id].i_get) {
|
||||
// queue got full
|
||||
emu_tasks[id].i_put = -1;
|
||||
}
|
||||
//printf("after ets_post: "); dump_task(prio, &emu_tasks[id]);
|
||||
//dump_tasks();
|
||||
|
||||
ets_intr_unlock();
|
||||
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int ets_loop_iter_disable = 0;
|
||||
|
||||
// to implement a 64-bit wide microsecond counter
|
||||
static uint32_t system_time_prev = 0;
|
||||
uint32_t system_time_high_word = 0;
|
||||
|
||||
bool ets_loop_iter(void) {
|
||||
if (ets_loop_iter_disable) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// handle overflow of system microsecond counter
|
||||
ets_intr_lock();
|
||||
uint32_t system_time_cur = system_get_time();
|
||||
if (system_time_cur < system_time_prev) {
|
||||
system_time_high_word += 1; // record overflow of low 32-bits
|
||||
}
|
||||
system_time_prev = system_time_cur;
|
||||
ets_intr_unlock();
|
||||
|
||||
//static unsigned cnt;
|
||||
bool progress = false;
|
||||
for (volatile struct task_entry *t = emu_tasks; t < &emu_tasks[MP_ARRAY_SIZE(emu_tasks)]; t++) {
|
||||
system_soft_wdt_feed();
|
||||
ets_intr_lock();
|
||||
//printf("etc_loop_iter: "); dump_task(t - emu_tasks + FIRST_PRIO, t);
|
||||
if (t->i_get != t->i_put) {
|
||||
progress = true;
|
||||
//printf("#%d Calling task %d(%p) (%x, %x)\n", cnt++,
|
||||
// t - emu_tasks + FIRST_PRIO, t->task, t->queue[t->i_get].sig, t->queue[t->i_get].par);
|
||||
int idx = t->i_get;
|
||||
if (t->i_put == -1) {
|
||||
t->i_put = t->i_get;
|
||||
}
|
||||
if (++t->i_get == t->qlen) {
|
||||
t->i_get = 0;
|
||||
}
|
||||
//ets_intr_unlock();
|
||||
t->task(&t->queue[idx]);
|
||||
//ets_intr_lock();
|
||||
//printf("Done calling task %d\n", t - emu_tasks + FIRST_PRIO);
|
||||
}
|
||||
ets_intr_unlock();
|
||||
}
|
||||
return progress;
|
||||
}
|
||||
|
||||
#if SDK_BELOW_1_1_1
|
||||
void my_timer_isr(void *arg) {
|
||||
// uart0_write_char('+');
|
||||
ets_post(0x1f, 0, 0);
|
||||
}
|
||||
|
||||
// Timer init func is in ROM, and calls ets_task by relative addr directly in ROM
|
||||
// so, we have to re-init task using our handler
|
||||
void ets_timer_init() {
|
||||
printf("ets_timer_init\n");
|
||||
// _ets_timer_init();
|
||||
ets_isr_attach(10, my_timer_isr, NULL);
|
||||
SET_PERI_REG_MASK(0x3FF00004, 4);
|
||||
ETS_INTR_ENABLE(10);
|
||||
ets_task((os_task_t)0x40002E3C, 0x1f, (os_event_t*)0x3FFFDDC0, 4);
|
||||
|
||||
WRITE_PERI_REG(PERIPHS_TIMER_BASEDDR + 0x30, 0);
|
||||
WRITE_PERI_REG(PERIPHS_TIMER_BASEDDR + 0x28, 0x88);
|
||||
WRITE_PERI_REG(PERIPHS_TIMER_BASEDDR + 0x30, 0);
|
||||
printf("Installed timer ISR\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
bool ets_run(void) {
|
||||
#if USE_ETS_TASK
|
||||
#if SDK_BELOW_1_1_1
|
||||
ets_isr_attach(10, my_timer_isr, NULL);
|
||||
#endif
|
||||
_ets_run();
|
||||
#else
|
||||
// ets_timer_init();
|
||||
*(char*)0x3FFFC6FC = 0;
|
||||
ets_intr_lock();
|
||||
printf("ets_alt_task: ets_run\n");
|
||||
#if DEBUG
|
||||
dump_tasks();
|
||||
#endif
|
||||
ets_intr_unlock();
|
||||
while (1) {
|
||||
if (!ets_loop_iter()) {
|
||||
//printf("idle\n");
|
||||
ets_intr_lock();
|
||||
if (idle_cb) {
|
||||
idle_cb(idle_arg);
|
||||
}
|
||||
asm("waiti 0");
|
||||
ets_intr_unlock();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void ets_set_idle_cb(void (*handler)(void *), void *arg) {
|
||||
//printf("ets_set_idle_cb(%p, %p)\n", handler, arg);
|
||||
idle_cb = handler;
|
||||
idle_arg = arg;
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
#ifndef MICROPY_INCLUDED_ESP8266_ETS_ALT_TASK_H
|
||||
#define MICROPY_INCLUDED_ESP8266_ETS_ALT_TASK_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
extern int ets_loop_iter_disable;
|
||||
extern uint32_t system_time_high_word;
|
||||
|
||||
bool ets_loop_iter(void);
|
||||
|
||||
#endif // MICROPY_INCLUDED_ESP8266_ETS_ALT_TASK_H
|
@ -1,45 +0,0 @@
|
||||
#ifndef MICROPY_INCLUDED_ESP8266_ETSHAL_H
|
||||
#define MICROPY_INCLUDED_ESP8266_ETSHAL_H
|
||||
|
||||
#include <os_type.h>
|
||||
|
||||
// see http://esp8266-re.foogod.com/wiki/Random_Number_Generator
|
||||
#define WDEV_HWRNG ((volatile uint32_t*)0x3ff20e44)
|
||||
|
||||
void ets_delay_us(uint16_t us);
|
||||
void ets_intr_lock(void);
|
||||
void ets_intr_unlock(void);
|
||||
void ets_isr_mask(uint32_t mask);
|
||||
void ets_isr_unmask(uint32_t mask);
|
||||
void ets_isr_attach(int irq_no, void (*handler)(void *), void *arg);
|
||||
void ets_install_putc1();
|
||||
void uart_div_modify(uint8_t uart, uint32_t divisor);
|
||||
void ets_set_idle_cb(void (*handler)(void *), void *arg);
|
||||
|
||||
void ets_timer_arm_new(os_timer_t *tim, uint32_t millis, bool repeat, bool is_milli_timer);
|
||||
void ets_timer_setfn(os_timer_t *tim, ETSTimerFunc callback, void *cb_data);
|
||||
void ets_timer_disarm(os_timer_t *tim);
|
||||
|
||||
extern void ets_wdt_disable(void);
|
||||
extern void wdt_feed(void);
|
||||
|
||||
// Opaque structure
|
||||
#ifndef MD5_CTX
|
||||
typedef char MD5_CTX[88];
|
||||
#endif
|
||||
|
||||
void MD5Init(MD5_CTX *context);
|
||||
void MD5Update(MD5_CTX *context, const void *data, unsigned int len);
|
||||
void MD5Final(unsigned char digest[16], MD5_CTX *context);
|
||||
|
||||
// These prototypes are for recent SDKs with "malloc tracking"
|
||||
void *pvPortMalloc(size_t sz, const char *fname, unsigned line);
|
||||
void *pvPortZalloc(size_t sz, const char *fname, unsigned line);
|
||||
void *pvPortRealloc(void *p, unsigned sz, const char *fname, unsigned line);
|
||||
void vPortFree(void *p, const char *fname, unsigned line);
|
||||
|
||||
uint32_t SPIRead(uint32_t offset, void *buf, uint32_t len);
|
||||
uint32_t SPIWrite(uint32_t offset, const void *buf, uint32_t len);
|
||||
uint32_t SPIEraseSector(int sector);
|
||||
|
||||
#endif // MICROPY_INCLUDED_ESP8266_ETSHAL_H
|
@ -1,43 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014, 2016 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 "py/obj.h"
|
||||
#include "lib/timeutils/timeutils.h"
|
||||
#include "lib/oofatfs/ff.h"
|
||||
#include "modmachine.h"
|
||||
|
||||
DWORD get_fattime(void) {
|
||||
|
||||
// TODO: Optimize division (there's no HW division support on ESP8266,
|
||||
// so it's expensive).
|
||||
uint32_t secs = (uint32_t)(pyb_rtc_get_us_since_2000() / 1000000);
|
||||
|
||||
timeutils_struct_time_t tm;
|
||||
timeutils_seconds_since_2000_to_struct_time(secs, &tm);
|
||||
|
||||
return (((DWORD)(tm.tm_year - 1980) << 25) | ((DWORD)tm.tm_mon << 21) | ((DWORD)tm.tm_mday << 16) |
|
||||
((DWORD)tm.tm_hour << 11) | ((DWORD)tm.tm_min << 5) | ((DWORD)tm.tm_sec >> 1));
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014 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/gc.h"
|
||||
#include "gccollect.h"
|
||||
|
||||
// As we do not have control over the application entry point, there is no way
|
||||
// to figure out the real stack base on runtime, so it needs to be hardcoded
|
||||
#define STACK_END 0x40000000
|
||||
|
||||
mp_uint_t gc_helper_get_regs_and_sp(mp_uint_t *regs);
|
||||
|
||||
void gc_collect(void) {
|
||||
// start the GC
|
||||
gc_collect_start();
|
||||
|
||||
// get the registers and the sp
|
||||
mp_uint_t regs[8];
|
||||
mp_uint_t sp = gc_helper_get_regs_and_sp(regs);
|
||||
|
||||
// trace the stack, including the registers (since they live on the stack in this function)
|
||||
gc_collect_root((void**)sp, (STACK_END - sp) / sizeof(uint32_t));
|
||||
|
||||
#if MICROPY_EMIT_XTENSA || MICROPY_EMIT_INLINE_XTENSA
|
||||
// trace any native code because it can contain pointers to the heap
|
||||
esp_native_code_gc_collect();
|
||||
#endif
|
||||
|
||||
// end the GC
|
||||
gc_collect_end();
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014 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_ESP8266_GCCOLLECT_H
|
||||
#define MICROPY_INCLUDED_ESP8266_GCCOLLECT_H
|
||||
|
||||
extern uint32_t _text_start;
|
||||
extern uint32_t _text_end;
|
||||
extern uint32_t _irom0_text_start;
|
||||
extern uint32_t _irom0_text_end;
|
||||
extern uint32_t _data_start;
|
||||
extern uint32_t _data_end;
|
||||
extern uint32_t _rodata_start;
|
||||
extern uint32_t _rodata_end;
|
||||
extern uint32_t _bss_start;
|
||||
extern uint32_t _bss_end;
|
||||
extern uint32_t _heap_start;
|
||||
extern uint32_t _heap_end;
|
||||
|
||||
void gc_collect(void);
|
||||
void esp_native_code_gc_collect(void);
|
||||
|
||||
#endif // MICROPY_INCLUDED_ESP8266_GCCOLLECT_H
|
@ -1,22 +0,0 @@
|
||||
.file "gchelper.s"
|
||||
.text
|
||||
|
||||
.align 4
|
||||
.global gc_helper_get_regs_and_sp
|
||||
.type gc_helper_get_regs_and_sp, @function
|
||||
gc_helper_get_regs_and_sp:
|
||||
# store regs into given array
|
||||
s32i.n a8, a2, 0
|
||||
s32i.n a9, a2, 4
|
||||
s32i.n a10, a2, 8
|
||||
s32i.n a11, a2, 12
|
||||
s32i.n a12, a2, 16
|
||||
s32i.n a13, a2, 20
|
||||
s32i.n a14, a2, 24
|
||||
s32i.n a15, a2, 28
|
||||
|
||||
# return the sp
|
||||
mov a2, a1
|
||||
ret.n
|
||||
|
||||
.size gc_helper_get_regs_and_sp, .-gc_helper_get_regs_and_sp
|
@ -1,54 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013-2016 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 "py/builtin.h"
|
||||
|
||||
const char esp_help_text[] =
|
||||
"Welcome to MicroPython!\n"
|
||||
"\n"
|
||||
"For online docs please visit http://docs.micropython.org/en/latest/esp8266/ .\n"
|
||||
"For diagnostic information to include in bug reports execute 'import port_diag'.\n"
|
||||
"\n"
|
||||
"Basic WiFi configuration:\n"
|
||||
"\n"
|
||||
"import network\n"
|
||||
"sta_if = network.WLAN(network.STA_IF); sta_if.active(True)\n"
|
||||
"sta_if.scan() # Scan for available access points\n"
|
||||
"sta_if.connect(\"<AP_name>\", \"<password>\") # Connect to an AP\n"
|
||||
"sta_if.isconnected() # Check for successful connection\n"
|
||||
"# Change name/password of ESP8266's AP:\n"
|
||||
"ap_if = network.WLAN(network.AP_IF)\n"
|
||||
"ap_if.config(essid=\"<AP_NAME>\", authmode=network.AUTH_WPA_WPA2_PSK, password=\"<password>\")\n"
|
||||
"\n"
|
||||
"Control commands:\n"
|
||||
" CTRL-A -- on a blank line, enter raw REPL mode\n"
|
||||
" CTRL-B -- on a blank line, enter normal REPL mode\n"
|
||||
" CTRL-C -- interrupt a running program\n"
|
||||
" CTRL-D -- on a blank line, do a soft reset of the board\n"
|
||||
" CTRL-E -- on a blank line, enter paste mode\n"
|
||||
"\n"
|
||||
"For further help on a specific object, type help(obj)\n"
|
||||
;
|
@ -1,331 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 David Ogilvy (MetalPhreak)
|
||||
* Modified 2016 by Radomir Dopieralski
|
||||
*
|
||||
* 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 "hspi.h"
|
||||
|
||||
/*
|
||||
Wrapper to setup HSPI/SPI GPIO pins and default SPI clock
|
||||
spi_no - SPI (0) or HSPI (1)
|
||||
Not used in MicroPython.
|
||||
*/
|
||||
void spi_init(uint8_t spi_no) {
|
||||
spi_init_gpio(spi_no, SPI_CLK_USE_DIV);
|
||||
spi_clock(spi_no, SPI_CLK_PREDIV, SPI_CLK_CNTDIV);
|
||||
spi_tx_byte_order(spi_no, SPI_BYTE_ORDER_HIGH_TO_LOW);
|
||||
spi_rx_byte_order(spi_no, SPI_BYTE_ORDER_HIGH_TO_LOW);
|
||||
|
||||
SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_CS_SETUP|SPI_CS_HOLD);
|
||||
CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_FLASH_MODE);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Configures SPI mode parameters for clock edge and clock polarity.
|
||||
spi_no - SPI (0) or HSPI (1)
|
||||
spi_cpha - (0) Data is valid on clock leading edge
|
||||
(1) Data is valid on clock trailing edge
|
||||
spi_cpol - (0) Clock is low when inactive
|
||||
(1) Clock is high when inactive
|
||||
For MicroPython this version is different from original.
|
||||
*/
|
||||
void spi_mode(uint8_t spi_no, uint8_t spi_cpha, uint8_t spi_cpol) {
|
||||
if (spi_cpol) {
|
||||
SET_PERI_REG_MASK(SPI_PIN(HSPI), SPI_IDLE_EDGE);
|
||||
} else {
|
||||
CLEAR_PERI_REG_MASK(SPI_PIN(HSPI), SPI_IDLE_EDGE);
|
||||
}
|
||||
if (spi_cpha == spi_cpol) {
|
||||
// Mode 3 - MOSI is set on falling edge of clock
|
||||
// Mode 0 - MOSI is set on falling edge of clock
|
||||
CLEAR_PERI_REG_MASK(SPI_USER(HSPI), SPI_CK_OUT_EDGE);
|
||||
SET_PERI_REG_MASK(SPI_USER(HSPI), SPI_CK_I_EDGE);
|
||||
} else {
|
||||
// Mode 2 - MOSI is set on rising edge of clock
|
||||
// Mode 1 - MOSI is set on rising edge of clock
|
||||
SET_PERI_REG_MASK(SPI_USER(HSPI), SPI_CK_OUT_EDGE);
|
||||
CLEAR_PERI_REG_MASK(SPI_USER(HSPI), SPI_CK_I_EDGE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Initialise the GPIO pins for use as SPI pins.
|
||||
spi_no - SPI (0) or HSPI (1)
|
||||
sysclk_as_spiclk -
|
||||
SPI_CLK_80MHZ_NODIV (1) if using 80MHz for SPI clock.
|
||||
SPI_CLK_USE_DIV (0) if using divider for lower speed.
|
||||
*/
|
||||
void spi_init_gpio(uint8_t spi_no, uint8_t sysclk_as_spiclk) {
|
||||
uint32_t clock_div_flag = 0;
|
||||
if (sysclk_as_spiclk) {
|
||||
clock_div_flag = 0x0001;
|
||||
}
|
||||
if (spi_no == SPI) {
|
||||
// Set bit 8 if 80MHz sysclock required
|
||||
WRITE_PERI_REG(PERIPHS_IO_MUX, 0x005 | (clock_div_flag<<8));
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CLK_U, 1);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_CMD_U, 1);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA0_U, 1);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_SD_DATA1_U, 1);
|
||||
} else if (spi_no == HSPI) {
|
||||
// Set bit 9 if 80MHz sysclock required
|
||||
WRITE_PERI_REG(PERIPHS_IO_MUX, 0x105 | (clock_div_flag<<9));
|
||||
// GPIO12 is HSPI MISO pin (Master Data In)
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDI_U, 2);
|
||||
// GPIO13 is HSPI MOSI pin (Master Data Out)
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTCK_U, 2);
|
||||
// GPIO14 is HSPI CLK pin (Clock)
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTMS_U, 2);
|
||||
// GPIO15 is HSPI CS pin (Chip Select / Slave Select)
|
||||
// In MicroPython, we are handling CS ourself in drivers.
|
||||
// PIN_FUNC_SELECT(PERIPHS_IO_MUX_MTDO_U, 2);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Set up the control registers for the SPI clock
|
||||
spi_no - SPI (0) or HSPI (1)
|
||||
prediv - predivider value (actual division value)
|
||||
cntdiv - postdivider value (actual division value)
|
||||
Set either divider to 0 to disable all division (80MHz sysclock)
|
||||
*/
|
||||
void spi_clock(uint8_t spi_no, uint16_t prediv, uint8_t cntdiv) {
|
||||
if (prediv == 0 || cntdiv == 0) {
|
||||
WRITE_PERI_REG(SPI_CLOCK(spi_no), SPI_CLK_EQU_SYSCLK);
|
||||
} else {
|
||||
WRITE_PERI_REG(SPI_CLOCK(spi_no),
|
||||
(((prediv - 1) & SPI_CLKDIV_PRE) << SPI_CLKDIV_PRE_S) |
|
||||
(((cntdiv - 1) & SPI_CLKCNT_N) << SPI_CLKCNT_N_S) |
|
||||
(((cntdiv >> 1) & SPI_CLKCNT_H) << SPI_CLKCNT_H_S) |
|
||||
((0 & SPI_CLKCNT_L) << SPI_CLKCNT_L_S)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Setup the byte order for shifting data out of buffer
|
||||
spi_no - SPI (0) or HSPI (1)
|
||||
byte_order -
|
||||
SPI_BYTE_ORDER_HIGH_TO_LOW (1)
|
||||
Data is sent out starting with Bit31 and down to Bit0
|
||||
SPI_BYTE_ORDER_LOW_TO_HIGH (0)
|
||||
Data is sent out starting with the lowest BYTE, from MSB to LSB,
|
||||
followed by the second lowest BYTE, from MSB to LSB, followed by
|
||||
the second highest BYTE, from MSB to LSB, followed by the highest
|
||||
BYTE, from MSB to LSB 0xABCDEFGH would be sent as 0xGHEFCDAB.
|
||||
*/
|
||||
void spi_tx_byte_order(uint8_t spi_no, uint8_t byte_order) {
|
||||
if (byte_order) {
|
||||
SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_WR_BYTE_ORDER);
|
||||
} else {
|
||||
CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_WR_BYTE_ORDER);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Setup the byte order for shifting data into buffer
|
||||
spi_no - SPI (0) or HSPI (1)
|
||||
byte_order -
|
||||
SPI_BYTE_ORDER_HIGH_TO_LOW (1)
|
||||
Data is read in starting with Bit31 and down to Bit0
|
||||
SPI_BYTE_ORDER_LOW_TO_HIGH (0)
|
||||
Data is read in starting with the lowest BYTE, from MSB to LSB,
|
||||
followed by the second lowest BYTE, from MSB to LSB, followed by
|
||||
the second highest BYTE, from MSB to LSB, followed by the highest
|
||||
BYTE, from MSB to LSB 0xABCDEFGH would be read as 0xGHEFCDAB
|
||||
*/
|
||||
void spi_rx_byte_order(uint8_t spi_no, uint8_t byte_order) {
|
||||
if (byte_order) {
|
||||
SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_RD_BYTE_ORDER);
|
||||
} else {
|
||||
CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_RD_BYTE_ORDER);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
SPI transaction function
|
||||
spi_no - SPI (0) or HSPI (1)
|
||||
cmd_bits - actual number of bits to transmit
|
||||
cmd_data - command data
|
||||
addr_bits - actual number of bits to transmit
|
||||
addr_data - address data
|
||||
dout_bits - actual number of bits to transmit
|
||||
dout_data - output data
|
||||
din_bits - actual number of bits to receive
|
||||
Returns: read data - uint32_t containing read in data only if RX was set
|
||||
0 - something went wrong (or actual read data was 0)
|
||||
1 - data sent ok (or actual read data is 1)
|
||||
Note: all data is assumed to be stored in the lower bits of the data variables
|
||||
(for anything <32 bits).
|
||||
*/
|
||||
uint32_t spi_transaction(uint8_t spi_no, uint8_t cmd_bits, uint16_t cmd_data,
|
||||
uint32_t addr_bits, uint32_t addr_data,
|
||||
uint32_t dout_bits, uint32_t dout_data,
|
||||
uint32_t din_bits, uint32_t dummy_bits) {
|
||||
while (spi_busy(spi_no)) {}; // Wait for SPI to be ready
|
||||
|
||||
// Enable SPI Functions
|
||||
// Disable MOSI, MISO, ADDR, COMMAND, DUMMY in case previously set.
|
||||
CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_MOSI | SPI_USR_MISO |
|
||||
SPI_USR_COMMAND | SPI_USR_ADDR | SPI_USR_DUMMY);
|
||||
|
||||
// Enable functions based on number of bits. 0 bits = disabled.
|
||||
// This is rather inefficient but allows for a very generic function.
|
||||
// CMD ADDR and MOSI are set below to save on an extra if statement.
|
||||
if (din_bits) {
|
||||
if (dout_bits) {
|
||||
SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_DOUTDIN);
|
||||
} else {
|
||||
SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_MISO);
|
||||
}
|
||||
}
|
||||
if (dummy_bits) {
|
||||
SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_DUMMY);
|
||||
}
|
||||
|
||||
// Setup Bitlengths
|
||||
WRITE_PERI_REG(SPI_USER1(spi_no),
|
||||
// Number of bits in Address
|
||||
((addr_bits - 1) & SPI_USR_ADDR_BITLEN) << SPI_USR_ADDR_BITLEN_S |
|
||||
// Number of bits to Send
|
||||
((dout_bits - 1) & SPI_USR_MOSI_BITLEN) << SPI_USR_MOSI_BITLEN_S |
|
||||
// Number of bits to receive
|
||||
((din_bits - 1) & SPI_USR_MISO_BITLEN) << SPI_USR_MISO_BITLEN_S |
|
||||
// Number of Dummy bits to insert
|
||||
((dummy_bits - 1) & SPI_USR_DUMMY_CYCLELEN) << SPI_USR_DUMMY_CYCLELEN_S);
|
||||
|
||||
// Setup Command Data
|
||||
if (cmd_bits) {
|
||||
// Enable COMMAND function in SPI module
|
||||
SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_COMMAND);
|
||||
// Align command data to high bits
|
||||
uint16_t command = cmd_data << (16-cmd_bits);
|
||||
// Swap byte order
|
||||
command = ((command>>8)&0xff) | ((command<<8)&0xff00);
|
||||
WRITE_PERI_REG(SPI_USER2(spi_no), (
|
||||
(((cmd_bits - 1) & SPI_USR_COMMAND_BITLEN) << SPI_USR_COMMAND_BITLEN_S) |
|
||||
(command & SPI_USR_COMMAND_VALUE)
|
||||
));
|
||||
}
|
||||
|
||||
// Setup Address Data
|
||||
if (addr_bits) {
|
||||
// Enable ADDRess function in SPI module
|
||||
SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_ADDR);
|
||||
// Align address data to high bits
|
||||
WRITE_PERI_REG(SPI_ADDR(spi_no), addr_data << (32 - addr_bits));
|
||||
}
|
||||
|
||||
// Setup DOUT data
|
||||
if (dout_bits) {
|
||||
// Enable MOSI function in SPI module
|
||||
SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_MOSI);
|
||||
// Copy data to W0
|
||||
if (READ_PERI_REG(SPI_USER(spi_no))&SPI_WR_BYTE_ORDER) {
|
||||
WRITE_PERI_REG(SPI_W0(spi_no), dout_data << (32 - dout_bits));
|
||||
} else {
|
||||
uint8_t dout_extra_bits = dout_bits%8;
|
||||
|
||||
if (dout_extra_bits) {
|
||||
// If your data isn't a byte multiple (8/16/24/32 bits) and you
|
||||
// don't have SPI_WR_BYTE_ORDER set, you need this to move the
|
||||
// non-8bit remainder to the MSBs. Not sure if there's even a use
|
||||
// case for this, but it's here if you need it... For example,
|
||||
// 0xDA4 12 bits without SPI_WR_BYTE_ORDER would usually be output
|
||||
// as if it were 0x0DA4, of which 0xA4, and then 0x0 would be
|
||||
// shifted out (first 8 bits of low byte, then 4 MSB bits of high
|
||||
// byte - ie reverse byte order).
|
||||
// The code below shifts it out as 0xA4 followed by 0xD as you
|
||||
// might require.
|
||||
WRITE_PERI_REG(SPI_W0(spi_no), (
|
||||
(0xFFFFFFFF << (dout_bits - dout_extra_bits) & dout_data)
|
||||
<< (8-dout_extra_bits) |
|
||||
((0xFFFFFFFF >> (32 - (dout_bits - dout_extra_bits)))
|
||||
& dout_data)
|
||||
));
|
||||
} else {
|
||||
WRITE_PERI_REG(SPI_W0(spi_no), dout_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Begin SPI Transaction
|
||||
SET_PERI_REG_MASK(SPI_CMD(spi_no), SPI_USR);
|
||||
|
||||
// Return DIN data
|
||||
if (din_bits) {
|
||||
while (spi_busy(spi_no)) {}; // Wait for SPI transaction to complete
|
||||
if (READ_PERI_REG(SPI_USER(spi_no))&SPI_RD_BYTE_ORDER) {
|
||||
// Assuming data in is written to MSB. TBC
|
||||
return READ_PERI_REG(SPI_W0(spi_no)) >> (32 - din_bits);
|
||||
} else {
|
||||
// Read in the same way as DOUT is sent. Note existing contents of
|
||||
// SPI_W0 remain unless overwritten!
|
||||
return READ_PERI_REG(SPI_W0(spi_no));
|
||||
}
|
||||
return 0; // Something went wrong
|
||||
}
|
||||
|
||||
// Transaction completed
|
||||
return 1; // Success
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Just do minimal work needed to send 8 bits.
|
||||
*/
|
||||
inline void spi_tx8fast(uint8_t spi_no, uint8_t dout_data) {
|
||||
while (spi_busy(spi_no)) {}; // Wait for SPI to be ready
|
||||
|
||||
// Enable SPI Functions
|
||||
// Disable MOSI, MISO, ADDR, COMMAND, DUMMY in case previously set.
|
||||
CLEAR_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_MOSI | SPI_USR_MISO |
|
||||
SPI_USR_COMMAND | SPI_USR_ADDR | SPI_USR_DUMMY);
|
||||
|
||||
// Setup Bitlengths
|
||||
WRITE_PERI_REG(SPI_USER1(spi_no),
|
||||
// Number of bits to Send
|
||||
((8 - 1) & SPI_USR_MOSI_BITLEN) << SPI_USR_MOSI_BITLEN_S |
|
||||
// Number of bits to receive
|
||||
((8 - 1) & SPI_USR_MISO_BITLEN) << SPI_USR_MISO_BITLEN_S);
|
||||
|
||||
|
||||
// Setup DOUT data
|
||||
// Enable MOSI function in SPI module
|
||||
SET_PERI_REG_MASK(SPI_USER(spi_no), SPI_USR_MOSI);
|
||||
// Copy data to W0
|
||||
if (READ_PERI_REG(SPI_USER(spi_no)) & SPI_WR_BYTE_ORDER) {
|
||||
WRITE_PERI_REG(SPI_W0(spi_no), dout_data << (32 - 8));
|
||||
} else {
|
||||
WRITE_PERI_REG(SPI_W0(spi_no), dout_data);
|
||||
}
|
||||
|
||||
// Begin SPI Transaction
|
||||
SET_PERI_REG_MASK(SPI_CMD(spi_no), SPI_USR);
|
||||
}
|
@ -1,79 +0,0 @@
|
||||
/*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 David Ogilvy (MetalPhreak)
|
||||
* Modified 2016 by Radomir Dopieralski
|
||||
*
|
||||
* 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 SPI_APP_H
|
||||
#define SPI_APP_H
|
||||
|
||||
#include "hspi_register.h"
|
||||
#include "ets_sys.h"
|
||||
#include "osapi.h"
|
||||
#include "os_type.h"
|
||||
|
||||
// Define SPI hardware modules
|
||||
#define SPI 0
|
||||
#define HSPI 1
|
||||
|
||||
#define SPI_CLK_USE_DIV 0
|
||||
#define SPI_CLK_80MHZ_NODIV 1
|
||||
|
||||
#define SPI_BYTE_ORDER_HIGH_TO_LOW 1
|
||||
#define SPI_BYTE_ORDER_LOW_TO_HIGH 0
|
||||
|
||||
#ifndef CPU_CLK_FREQ //Should already be defined in eagle_soc.h
|
||||
#define CPU_CLK_FREQ (80 * 1000000)
|
||||
#endif
|
||||
|
||||
// Define some default SPI clock settings
|
||||
#define SPI_CLK_PREDIV 10
|
||||
#define SPI_CLK_CNTDIV 2
|
||||
#define SPI_CLK_FREQ (CPU_CLK_FREQ / (SPI_CLK_PREDIV * SPI_CLK_CNTDIV))
|
||||
// 80 / 20 = 4 MHz
|
||||
|
||||
void spi_init(uint8_t spi_no);
|
||||
void spi_mode(uint8_t spi_no, uint8_t spi_cpha,uint8_t spi_cpol);
|
||||
void spi_init_gpio(uint8_t spi_no, uint8_t sysclk_as_spiclk);
|
||||
void spi_clock(uint8_t spi_no, uint16_t prediv, uint8_t cntdiv);
|
||||
void spi_tx_byte_order(uint8_t spi_no, uint8_t byte_order);
|
||||
void spi_rx_byte_order(uint8_t spi_no, uint8_t byte_order);
|
||||
uint32_t spi_transaction(uint8_t spi_no, uint8_t cmd_bits, uint16_t cmd_data,
|
||||
uint32_t addr_bits, uint32_t addr_data,
|
||||
uint32_t dout_bits, uint32_t dout_data,
|
||||
uint32_t din_bits, uint32_t dummy_bits);
|
||||
void spi_tx8fast(uint8_t spi_no, uint8_t dout_data);
|
||||
|
||||
// Expansion Macros
|
||||
#define spi_busy(spi_no) READ_PERI_REG(SPI_CMD(spi_no))&SPI_USR
|
||||
|
||||
#define spi_txd(spi_no, bits, data) spi_transaction(spi_no, 0, 0, 0, 0, bits, (uint32_t) data, 0, 0)
|
||||
#define spi_tx8(spi_no, data) spi_transaction(spi_no, 0, 0, 0, 0, 8, (uint32_t) data, 0, 0)
|
||||
#define spi_tx16(spi_no, data) spi_transaction(spi_no, 0, 0, 0, 0, 16, (uint32_t) data, 0, 0)
|
||||
#define spi_tx32(spi_no, data) spi_transaction(spi_no, 0, 0, 0, 0, 32, (uint32_t) data, 0, 0)
|
||||
|
||||
#define spi_rxd(spi_no, bits) spi_transaction(spi_no, 0, 0, 0, 0, 0, 0, bits, 0)
|
||||
#define spi_rx8(spi_no) spi_transaction(spi_no, 0, 0, 0, 0, 0, 0, 8, 0)
|
||||
#define spi_rx16(spi_no) spi_transaction(spi_no, 0, 0, 0, 0, 0, 0, 16, 0)
|
||||
#define spi_rx32(spi_no) spi_transaction(spi_no, 0, 0, 0, 0, 0, 0, 32, 0)
|
||||
|
||||
#endif
|
@ -1,278 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2010 - 2011 Espressif System
|
||||
* Modified by David Ogilvy (MetalPhreak)
|
||||
* Based on original file included in SDK 1.0.0
|
||||
*
|
||||
* Missing defines from previous SDK versions have
|
||||
* been added and are noted with comments. The
|
||||
* names of these defines are likely to change.
|
||||
*/
|
||||
|
||||
#ifndef SPI_REGISTER_H_INCLUDED
|
||||
#define SPI_REGISTER_H_INCLUDED
|
||||
|
||||
#define REG_SPI_BASE(i) (0x60000200-i*0x100)
|
||||
|
||||
#define SPI_CMD(i) (REG_SPI_BASE(i) + 0x0)
|
||||
#define SPI_FLASH_READ (BIT(31)) //From previous SDK
|
||||
#define SPI_FLASH_WREN (BIT(30)) //From previous SDK
|
||||
#define SPI_FLASH_WRDI (BIT(29)) //From previous SDK
|
||||
#define SPI_FLASH_RDID (BIT(28)) //From previous SDK
|
||||
#define SPI_FLASH_RDSR (BIT(27)) //From previous SDK
|
||||
#define SPI_FLASH_WRSR (BIT(26)) //From previous SDK
|
||||
#define SPI_FLASH_PP (BIT(25)) //From previous SDK
|
||||
#define SPI_FLASH_SE (BIT(24)) //From previous SDK
|
||||
#define SPI_FLASH_BE (BIT(23)) //From previous SDK
|
||||
#define SPI_FLASH_CE (BIT(22)) //From previous SDK
|
||||
#define SPI_FLASH_DP (BIT(21)) //From previous SDK
|
||||
#define SPI_FLASH_RES (BIT(20)) //From previous SDK
|
||||
#define SPI_FLASH_HPM (BIT(19)) //From previous SDK
|
||||
#define SPI_USR (BIT(18))
|
||||
|
||||
#define SPI_ADDR(i) (REG_SPI_BASE(i) + 0x4)
|
||||
|
||||
#define SPI_CTRL(i) (REG_SPI_BASE(i) + 0x8)
|
||||
#define SPI_WR_BIT_ORDER (BIT(26))
|
||||
#define SPI_RD_BIT_ORDER (BIT(25))
|
||||
#define SPI_QIO_MODE (BIT(24))
|
||||
#define SPI_DIO_MODE (BIT(23))
|
||||
#define SPI_TWO_BYTE_STATUS_EN (BIT(22)) //From previous SDK
|
||||
#define SPI_WP_REG (BIT(21)) //From previous SDK
|
||||
#define SPI_QOUT_MODE (BIT(20))
|
||||
#define SPI_SHARE_BUS (BIT(19)) //From previous SDK
|
||||
#define SPI_HOLD_MODE (BIT(18)) //From previous SDK
|
||||
#define SPI_ENABLE_AHB (BIT(17)) //From previous SDK
|
||||
#define SPI_SST_AAI (BIT(16)) //From previous SDK
|
||||
#define SPI_RESANDRES (BIT(15)) //From previous SDK
|
||||
#define SPI_DOUT_MODE (BIT(14))
|
||||
#define SPI_FASTRD_MODE (BIT(13))
|
||||
|
||||
#define SPI_CTRL1(i) (REG_SPI_BASE (i) + 0xC) //From previous SDK. Removed _FLASH_ from name to match other registers.
|
||||
#define SPI_CS_HOLD_DELAY 0x0000000F //Espressif BBS
|
||||
#define SPI_CS_HOLD_DELAY_S 28 //Espressif BBS
|
||||
#define SPI_CS_HOLD_DELAY_RES 0x00000FFF //Espressif BBS
|
||||
#define SPI_CS_HOLD_DELAY_RES_S 16 //Espressif BBS
|
||||
#define SPI_BUS_TIMER_LIMIT 0x0000FFFF //From previous SDK
|
||||
#define SPI_BUS_TIMER_LIMIT_S 0 //From previous SDK
|
||||
|
||||
|
||||
#define SPI_RD_STATUS(i) (REG_SPI_BASE(i) + 0x10)
|
||||
#define SPI_STATUS_EXT 0x000000FF //From previous SDK
|
||||
#define SPI_STATUS_EXT_S 24 //From previous SDK
|
||||
#define SPI_WB_MODE 0x000000FF //From previous SDK
|
||||
#define SPI_WB_MODE_S 16 //From previous SDK
|
||||
#define SPI_FLASH_STATUS_PRO_FLAG (BIT(7)) //From previous SDK
|
||||
#define SPI_FLASH_TOP_BOT_PRO_FLAG (BIT(5)) //From previous SDK
|
||||
#define SPI_FLASH_BP2 (BIT(4)) //From previous SDK
|
||||
#define SPI_FLASH_BP1 (BIT(3)) //From previous SDK
|
||||
#define SPI_FLASH_BP0 (BIT(2)) //From previous SDK
|
||||
#define SPI_FLASH_WRENABLE_FLAG (BIT(1)) //From previous SDK
|
||||
#define SPI_FLASH_BUSY_FLAG (BIT(0)) //From previous SDK
|
||||
|
||||
#define SPI_CTRL2(i) (REG_SPI_BASE(i) + 0x14)
|
||||
#define SPI_CS_DELAY_NUM 0x0000000F
|
||||
#define SPI_CS_DELAY_NUM_S 28
|
||||
#define SPI_CS_DELAY_MODE 0x00000003
|
||||
#define SPI_CS_DELAY_MODE_S 26
|
||||
#define SPI_MOSI_DELAY_NUM 0x00000007
|
||||
#define SPI_MOSI_DELAY_NUM_S 23
|
||||
#define SPI_MOSI_DELAY_MODE 0x00000003 //mode 0 : posedge; data set at positive edge of clk
|
||||
//mode 1 : negedge + 1 cycle delay, only if freq<10MHz ; data set at negitive edge of clk
|
||||
//mode 2 : Do not use this mode.
|
||||
#define SPI_MOSI_DELAY_MODE_S 21
|
||||
#define SPI_MISO_DELAY_NUM 0x00000007
|
||||
#define SPI_MISO_DELAY_NUM_S 18
|
||||
#define SPI_MISO_DELAY_MODE 0x00000003
|
||||
#define SPI_MISO_DELAY_MODE_S 16
|
||||
#define SPI_CK_OUT_HIGH_MODE 0x0000000F
|
||||
#define SPI_CK_OUT_HIGH_MODE_S 12
|
||||
#define SPI_CK_OUT_LOW_MODE 0x0000000F
|
||||
#define SPI_CK_OUT_LOW_MODE_S 8
|
||||
#define SPI_HOLD_TIME 0x0000000F
|
||||
#define SPI_HOLD_TIME_S 4
|
||||
#define SPI_SETUP_TIME 0x0000000F
|
||||
#define SPI_SETUP_TIME_S 0
|
||||
|
||||
#define SPI_CLOCK(i) (REG_SPI_BASE(i) + 0x18)
|
||||
#define SPI_CLK_EQU_SYSCLK (BIT(31))
|
||||
#define SPI_CLKDIV_PRE 0x00001FFF
|
||||
#define SPI_CLKDIV_PRE_S 18
|
||||
#define SPI_CLKCNT_N 0x0000003F
|
||||
#define SPI_CLKCNT_N_S 12
|
||||
#define SPI_CLKCNT_H 0x0000003F
|
||||
#define SPI_CLKCNT_H_S 6
|
||||
#define SPI_CLKCNT_L 0x0000003F
|
||||
#define SPI_CLKCNT_L_S 0
|
||||
|
||||
#define SPI_USER(i) (REG_SPI_BASE(i) + 0x1C)
|
||||
#define SPI_USR_COMMAND (BIT(31))
|
||||
#define SPI_USR_ADDR (BIT(30))
|
||||
#define SPI_USR_DUMMY (BIT(29))
|
||||
#define SPI_USR_MISO (BIT(28))
|
||||
#define SPI_USR_MOSI (BIT(27))
|
||||
#define SPI_USR_DUMMY_IDLE (BIT(26)) //From previous SDK
|
||||
#define SPI_USR_MOSI_HIGHPART (BIT(25))
|
||||
#define SPI_USR_MISO_HIGHPART (BIT(24))
|
||||
#define SPI_USR_PREP_HOLD (BIT(23)) //From previous SDK
|
||||
#define SPI_USR_CMD_HOLD (BIT(22)) //From previous SDK
|
||||
#define SPI_USR_ADDR_HOLD (BIT(21)) //From previous SDK
|
||||
#define SPI_USR_DUMMY_HOLD (BIT(20)) //From previous SDK
|
||||
#define SPI_USR_DIN_HOLD (BIT(19)) //From previous SDK
|
||||
#define SPI_USR_DOUT_HOLD (BIT(18)) //From previous SDK
|
||||
#define SPI_USR_HOLD_POL (BIT(17)) //From previous SDK
|
||||
#define SPI_SIO (BIT(16))
|
||||
#define SPI_FWRITE_QIO (BIT(15))
|
||||
#define SPI_FWRITE_DIO (BIT(14))
|
||||
#define SPI_FWRITE_QUAD (BIT(13))
|
||||
#define SPI_FWRITE_DUAL (BIT(12))
|
||||
#define SPI_WR_BYTE_ORDER (BIT(11))
|
||||
#define SPI_RD_BYTE_ORDER (BIT(10))
|
||||
#define SPI_AHB_ENDIAN_MODE 0x00000003 //From previous SDK
|
||||
#define SPI_AHB_ENDIAN_MODE_S 8 //From previous SDK
|
||||
#define SPI_CK_OUT_EDGE (BIT(7))
|
||||
#define SPI_CK_I_EDGE (BIT(6))
|
||||
#define SPI_CS_SETUP (BIT(5))
|
||||
#define SPI_CS_HOLD (BIT(4))
|
||||
#define SPI_AHB_USR_COMMAND (BIT(3)) //From previous SDK
|
||||
#define SPI_FLASH_MODE (BIT(2))
|
||||
#define SPI_AHB_USR_COMMAND_4BYTE (BIT(1)) //From previous SDK
|
||||
#define SPI_DOUTDIN (BIT(0)) //From previous SDK
|
||||
|
||||
//AHB = http://en.wikipedia.org/wiki/Advanced_Microcontroller_Bus_Architecture ?
|
||||
|
||||
|
||||
#define SPI_USER1(i) (REG_SPI_BASE(i) + 0x20)
|
||||
#define SPI_USR_ADDR_BITLEN 0x0000003F
|
||||
#define SPI_USR_ADDR_BITLEN_S 26
|
||||
#define SPI_USR_MOSI_BITLEN 0x000001FF
|
||||
#define SPI_USR_MOSI_BITLEN_S 17
|
||||
#define SPI_USR_MISO_BITLEN 0x000001FF
|
||||
#define SPI_USR_MISO_BITLEN_S 8
|
||||
#define SPI_USR_DUMMY_CYCLELEN 0x000000FF
|
||||
#define SPI_USR_DUMMY_CYCLELEN_S 0
|
||||
|
||||
#define SPI_USER2(i) (REG_SPI_BASE(i) + 0x24)
|
||||
#define SPI_USR_COMMAND_BITLEN 0x0000000F
|
||||
#define SPI_USR_COMMAND_BITLEN_S 28
|
||||
#define SPI_USR_COMMAND_VALUE 0x0000FFFF
|
||||
#define SPI_USR_COMMAND_VALUE_S 0
|
||||
|
||||
#define SPI_WR_STATUS(i) (REG_SPI_BASE(i) + 0x28)
|
||||
//previously defined as SPI_FLASH_USER3. No further info available.
|
||||
|
||||
#define SPI_PIN(i) (REG_SPI_BASE(i) + 0x2C)
|
||||
#define SPI_IDLE_EDGE (BIT(29))
|
||||
#define SPI_CS2_DIS (BIT(2))
|
||||
#define SPI_CS1_DIS (BIT(1))
|
||||
#define SPI_CS0_DIS (BIT(0))
|
||||
|
||||
#define SPI_SLAVE(i) (REG_SPI_BASE(i) + 0x30)
|
||||
#define SPI_SYNC_RESET (BIT(31))
|
||||
#define SPI_SLAVE_MODE (BIT(30))
|
||||
#define SPI_SLV_WR_RD_BUF_EN (BIT(29))
|
||||
#define SPI_SLV_WR_RD_STA_EN (BIT(28))
|
||||
#define SPI_SLV_CMD_DEFINE (BIT(27))
|
||||
#define SPI_TRANS_CNT 0x0000000F
|
||||
#define SPI_TRANS_CNT_S 23
|
||||
#define SPI_SLV_LAST_STATE 0x00000007 //From previous SDK
|
||||
#define SPI_SLV_LAST_STATE_S 20 //From previous SDK
|
||||
#define SPI_SLV_LAST_COMMAND 0x00000007 //From previous SDK
|
||||
#define SPI_SLV_LAST_COMMAND_S 17 //From previous SDK
|
||||
#define SPI_CS_I_MODE 0x00000003 //From previous SDK
|
||||
#define SPI_CS_I_MODE_S 10 //From previous SDK
|
||||
#define SPI_TRANS_DONE_EN (BIT(9))
|
||||
#define SPI_SLV_WR_STA_DONE_EN (BIT(8))
|
||||
#define SPI_SLV_RD_STA_DONE_EN (BIT(7))
|
||||
#define SPI_SLV_WR_BUF_DONE_EN (BIT(6))
|
||||
#define SPI_SLV_RD_BUF_DONE_EN (BIT(5))
|
||||
#define SLV_SPI_INT_EN 0x0000001f
|
||||
#define SLV_SPI_INT_EN_S 5
|
||||
#define SPI_TRANS_DONE (BIT(4))
|
||||
#define SPI_SLV_WR_STA_DONE (BIT(3))
|
||||
#define SPI_SLV_RD_STA_DONE (BIT(2))
|
||||
#define SPI_SLV_WR_BUF_DONE (BIT(1))
|
||||
#define SPI_SLV_RD_BUF_DONE (BIT(0))
|
||||
|
||||
#define SPI_SLAVE1(i) (REG_SPI_BASE(i) + 0x34)
|
||||
#define SPI_SLV_STATUS_BITLEN 0x0000001F
|
||||
#define SPI_SLV_STATUS_BITLEN_S 27
|
||||
#define SPI_SLV_STATUS_FAST_EN (BIT(26)) //From previous SDK
|
||||
#define SPI_SLV_STATUS_READBACK (BIT(25)) //From previous SDK
|
||||
#define SPI_SLV_BUF_BITLEN 0x000001FF
|
||||
#define SPI_SLV_BUF_BITLEN_S 16
|
||||
#define SPI_SLV_RD_ADDR_BITLEN 0x0000003F
|
||||
#define SPI_SLV_RD_ADDR_BITLEN_S 10
|
||||
#define SPI_SLV_WR_ADDR_BITLEN 0x0000003F
|
||||
#define SPI_SLV_WR_ADDR_BITLEN_S 4
|
||||
#define SPI_SLV_WRSTA_DUMMY_EN (BIT(3))
|
||||
#define SPI_SLV_RDSTA_DUMMY_EN (BIT(2))
|
||||
#define SPI_SLV_WRBUF_DUMMY_EN (BIT(1))
|
||||
#define SPI_SLV_RDBUF_DUMMY_EN (BIT(0))
|
||||
|
||||
|
||||
|
||||
#define SPI_SLAVE2(i) (REG_SPI_BASE(i) + 0x38)
|
||||
#define SPI_SLV_WRBUF_DUMMY_CYCLELEN 0X000000FF
|
||||
#define SPI_SLV_WRBUF_DUMMY_CYCLELEN_S 24
|
||||
#define SPI_SLV_RDBUF_DUMMY_CYCLELEN 0X000000FF
|
||||
#define SPI_SLV_RDBUF_DUMMY_CYCLELEN_S 16
|
||||
#define SPI_SLV_WRSTR_DUMMY_CYCLELEN 0X000000FF
|
||||
#define SPI_SLV_WRSTR_DUMMY_CYCLELEN_S 8
|
||||
#define SPI_SLV_RDSTR_DUMMY_CYCLELEN 0x000000FF
|
||||
#define SPI_SLV_RDSTR_DUMMY_CYCLELEN_S 0
|
||||
|
||||
#define SPI_SLAVE3(i) (REG_SPI_BASE(i) + 0x3C)
|
||||
#define SPI_SLV_WRSTA_CMD_VALUE 0x000000FF
|
||||
#define SPI_SLV_WRSTA_CMD_VALUE_S 24
|
||||
#define SPI_SLV_RDSTA_CMD_VALUE 0x000000FF
|
||||
#define SPI_SLV_RDSTA_CMD_VALUE_S 16
|
||||
#define SPI_SLV_WRBUF_CMD_VALUE 0x000000FF
|
||||
#define SPI_SLV_WRBUF_CMD_VALUE_S 8
|
||||
#define SPI_SLV_RDBUF_CMD_VALUE 0x000000FF
|
||||
#define SPI_SLV_RDBUF_CMD_VALUE_S 0
|
||||
|
||||
//Previous SDKs referred to these following registers as SPI_C0 etc.
|
||||
|
||||
#define SPI_W0(i) (REG_SPI_BASE(i) +0x40)
|
||||
#define SPI_W1(i) (REG_SPI_BASE(i) +0x44)
|
||||
#define SPI_W2(i) (REG_SPI_BASE(i) +0x48)
|
||||
#define SPI_W3(i) (REG_SPI_BASE(i) +0x4C)
|
||||
#define SPI_W4(i) (REG_SPI_BASE(i) +0x50)
|
||||
#define SPI_W5(i) (REG_SPI_BASE(i) +0x54)
|
||||
#define SPI_W6(i) (REG_SPI_BASE(i) +0x58)
|
||||
#define SPI_W7(i) (REG_SPI_BASE(i) +0x5C)
|
||||
#define SPI_W8(i) (REG_SPI_BASE(i) +0x60)
|
||||
#define SPI_W9(i) (REG_SPI_BASE(i) +0x64)
|
||||
#define SPI_W10(i) (REG_SPI_BASE(i) +0x68)
|
||||
#define SPI_W11(i) (REG_SPI_BASE(i) +0x6C)
|
||||
#define SPI_W12(i) (REG_SPI_BASE(i) +0x70)
|
||||
#define SPI_W13(i) (REG_SPI_BASE(i) +0x74)
|
||||
#define SPI_W14(i) (REG_SPI_BASE(i) +0x78)
|
||||
#define SPI_W15(i) (REG_SPI_BASE(i) +0x7C)
|
||||
|
||||
// +0x80 to +0xBC could be SPI_W16 through SPI_W31?
|
||||
|
||||
// +0xC0 to +0xEC not currently defined.
|
||||
|
||||
#define SPI_EXT0(i) (REG_SPI_BASE(i) + 0xF0) //From previous SDK. Removed _FLASH_ from name to match other registers.
|
||||
#define SPI_T_PP_ENA (BIT(31)) //From previous SDK
|
||||
#define SPI_T_PP_SHIFT 0x0000000F //From previous SDK
|
||||
#define SPI_T_PP_SHIFT_S 16 //From previous SDK
|
||||
#define SPI_T_PP_TIME 0x00000FFF //From previous SDK
|
||||
#define SPI_T_PP_TIME_S 0 //From previous SDK
|
||||
|
||||
#define SPI_EXT1(i) (REG_SPI_BASE(i) + 0xF4) //From previous SDK. Removed _FLASH_ from name to match other registers.
|
||||
#define SPI_T_ERASE_ENA (BIT(31)) //From previous SDK
|
||||
#define SPI_T_ERASE_SHIFT 0x0000000F //From previous SDK
|
||||
#define SPI_T_ERASE_SHIFT_S 16 //From previous SDK
|
||||
#define SPI_T_ERASE_TIME 0x00000FFF //From previous SDK
|
||||
#define SPI_T_ERASE_TIME_S 0 //From previous SDK
|
||||
|
||||
#define SPI_EXT2(i) (REG_SPI_BASE(i) + 0xF8) //From previous SDK. Removed _FLASH_ from name to match other registers.
|
||||
#define SPI_ST 0x00000007 //From previous SDK
|
||||
#define SPI_ST_S 0 //From previous SDK
|
||||
|
||||
#define SPI_EXT3(i) (REG_SPI_BASE(i) + 0xFC)
|
||||
#define SPI_INT_HOLD_ENA 0x00000003
|
||||
#define SPI_INT_HOLD_ENA_S 0
|
||||
#endif // SPI_REGISTER_H_INCLUDED
|
@ -1,43 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 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 "etshal.h"
|
||||
#include "ets_alt_task.h"
|
||||
|
||||
#include "modmachine.h"
|
||||
#include "common-hal/pulseio/PulseIn.h"
|
||||
|
||||
// this is in a separate file so it can go in iRAM
|
||||
void pin_intr_handler_iram(void *arg) {
|
||||
uint32_t status = GPIO_REG_READ(GPIO_STATUS_ADDRESS);
|
||||
GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, status);
|
||||
|
||||
// machine.Pin handlers
|
||||
pin_intr_handler(status);
|
||||
|
||||
// microcontroller.Pin handlers
|
||||
microcontroller_pin_call_intr_handlers(status);
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013-2016 Damien P. George
|
||||
* 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 "py/lexer.h"
|
||||
|
||||
#if MICROPY_ENABLE_COMPILER
|
||||
|
||||
typedef struct _mp_lexer_str32_buf_t {
|
||||
const uint32_t *src_cur;
|
||||
uint32_t val;
|
||||
uint8_t byte_off;
|
||||
} mp_lexer_str32_buf_t;
|
||||
|
||||
STATIC mp_uint_t str32_buf_next_byte(void *sb_in) {
|
||||
mp_lexer_str32_buf_t *sb = (mp_lexer_str32_buf_t*)sb_in;
|
||||
byte c = sb->val & 0xff;
|
||||
if (c == 0) {
|
||||
return MP_READER_EOF;
|
||||
}
|
||||
|
||||
if (++sb->byte_off > 3) {
|
||||
sb->byte_off = 0;
|
||||
sb->val = *sb->src_cur++;
|
||||
} else {
|
||||
sb->val >>= 8;
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
STATIC void str32_buf_free(void *sb_in) {
|
||||
mp_lexer_str32_buf_t *sb = (mp_lexer_str32_buf_t*)sb_in;
|
||||
m_del_obj(mp_lexer_str32_buf_t, sb);
|
||||
}
|
||||
|
||||
mp_lexer_t *mp_lexer_new_from_str32(qstr src_name, const char *str, mp_uint_t len, mp_uint_t free_len) {
|
||||
mp_lexer_str32_buf_t *sb = m_new_obj(mp_lexer_str32_buf_t);
|
||||
sb->byte_off = (uint32_t)str & 3;
|
||||
sb->src_cur = (uint32_t*)(str - sb->byte_off);
|
||||
sb->val = *sb->src_cur++ >> sb->byte_off * 8;
|
||||
mp_reader_t reader = {sb, str32_buf_next_byte, str32_buf_free};
|
||||
return mp_lexer_new(src_name, reader);
|
||||
}
|
||||
|
||||
#endif // MICROPY_ENABLE_COMPILER
|
@ -1,82 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Josef Gajdusek
|
||||
*
|
||||
* 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 "supervisor/shared/translate.h"
|
||||
#include "user_interface.h"
|
||||
|
||||
const mp_obj_type_t pyb_adc_type;
|
||||
|
||||
typedef struct _pyb_adc_obj_t {
|
||||
mp_obj_base_t base;
|
||||
bool isvdd;
|
||||
} pyb_adc_obj_t;
|
||||
|
||||
STATIC pyb_adc_obj_t pyb_adc_vdd3 = {{&pyb_adc_type}, true};
|
||||
STATIC pyb_adc_obj_t pyb_adc_adc = {{&pyb_adc_type}, false};
|
||||
|
||||
STATIC mp_obj_t pyb_adc_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw,
|
||||
const mp_obj_t *args) {
|
||||
mp_arg_check_num(n_args, n_kw, 1, 1, false);
|
||||
|
||||
mp_int_t chn = mp_obj_get_int(args[0]);
|
||||
|
||||
switch (chn) {
|
||||
case 0:
|
||||
return &pyb_adc_adc;
|
||||
case 1:
|
||||
return &pyb_adc_vdd3;
|
||||
default:
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
|
||||
translate("not a valid ADC Channel: %d"), chn));
|
||||
}
|
||||
}
|
||||
|
||||
STATIC mp_obj_t pyb_adc_read(mp_obj_t self_in) {
|
||||
pyb_adc_obj_t *adc = self_in;
|
||||
|
||||
if (adc->isvdd) {
|
||||
return mp_obj_new_int(system_get_vdd33());
|
||||
} else {
|
||||
return mp_obj_new_int(system_adc_read());
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_adc_read_obj, pyb_adc_read);
|
||||
|
||||
STATIC const mp_rom_map_elem_t pyb_adc_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&pyb_adc_read_obj) }
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(pyb_adc_locals_dict, pyb_adc_locals_dict_table);
|
||||
|
||||
const mp_obj_type_t pyb_adc_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_ADC,
|
||||
.make_new = pyb_adc_make_new,
|
||||
.locals_dict = (mp_obj_dict_t*)&pyb_adc_locals_dict,
|
||||
};
|
@ -1,187 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 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 <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ets_sys.h"
|
||||
#include "etshal.h"
|
||||
#include "ets_alt_task.h"
|
||||
|
||||
#include "py/runtime.h"
|
||||
#include "py/stream.h"
|
||||
#include "py/mphal.h"
|
||||
#include "extmod/machine_spi.h"
|
||||
#include "modmachine.h"
|
||||
#include "supervisor/shared/translate.h"
|
||||
#include "hspi.h"
|
||||
|
||||
#if MICROPY_PY_MACHINE_SPI
|
||||
|
||||
typedef struct _machine_hspi_obj_t {
|
||||
mp_obj_base_t base;
|
||||
uint32_t baudrate;
|
||||
uint8_t polarity;
|
||||
uint8_t phase;
|
||||
} machine_hspi_obj_t;
|
||||
|
||||
STATIC void machine_hspi_transfer(mp_obj_base_t *self_in, size_t len, const uint8_t *src, uint8_t *dest) {
|
||||
(void)self_in;
|
||||
|
||||
if (dest == NULL) {
|
||||
// fast case when we only need to write data
|
||||
size_t chunk_size = 1024;
|
||||
size_t count = len / chunk_size;
|
||||
size_t i = 0;
|
||||
for (size_t j = 0; j < count; ++j) {
|
||||
for (size_t k = 0; k < chunk_size; ++k) {
|
||||
spi_tx8fast(HSPI, src[i]);
|
||||
++i;
|
||||
}
|
||||
ets_loop_iter();
|
||||
}
|
||||
while (i < len) {
|
||||
spi_tx8fast(HSPI, src[i]);
|
||||
++i;
|
||||
}
|
||||
// wait for SPI transaction to complete
|
||||
while (spi_busy(HSPI)) {
|
||||
}
|
||||
} else {
|
||||
// we need to read and write data
|
||||
|
||||
// Process data in chunks, let the pending tasks run in between
|
||||
size_t chunk_size = 1024; // TODO this should depend on baudrate
|
||||
size_t count = len / chunk_size;
|
||||
size_t i = 0;
|
||||
for (size_t j = 0; j < count; ++j) {
|
||||
for (size_t k = 0; k < chunk_size; ++k) {
|
||||
dest[i] = spi_transaction(HSPI, 0, 0, 0, 0, 8, src[i], 8, 0);
|
||||
++i;
|
||||
}
|
||||
ets_loop_iter();
|
||||
}
|
||||
while (i < len) {
|
||||
dest[i] = spi_transaction(HSPI, 0, 0, 0, 0, 8, src[i], 8, 0);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
// MicroPython bindings for HSPI
|
||||
|
||||
STATIC void machine_hspi_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
machine_hspi_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
mp_printf(print, "HSPI(id=1, baudrate=%u, polarity=%u, phase=%u)",
|
||||
self->baudrate, self->polarity, self->phase);
|
||||
}
|
||||
|
||||
STATIC void machine_hspi_init(mp_obj_base_t *self_in, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
machine_hspi_obj_t *self = (machine_hspi_obj_t*)self_in;
|
||||
|
||||
enum { ARG_baudrate, ARG_polarity, ARG_phase };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_baudrate, MP_ARG_INT, {.u_int = -1} },
|
||||
{ MP_QSTR_polarity, MP_ARG_INT, {.u_int = -1} },
|
||||
{ MP_QSTR_phase, MP_ARG_INT, {.u_int = -1} },
|
||||
};
|
||||
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_baudrate].u_int != -1) {
|
||||
self->baudrate = args[ARG_baudrate].u_int;
|
||||
}
|
||||
if (args[ARG_polarity].u_int != -1) {
|
||||
self->polarity = args[ARG_polarity].u_int;
|
||||
}
|
||||
if (args[ARG_phase].u_int != -1) {
|
||||
self->phase = args[ARG_phase].u_int;
|
||||
}
|
||||
if (self->baudrate == 80000000L) {
|
||||
// Special case for full speed.
|
||||
spi_init_gpio(HSPI, SPI_CLK_80MHZ_NODIV);
|
||||
spi_clock(HSPI, 0, 0);
|
||||
} else if (self->baudrate > 40000000L) {
|
||||
mp_raise_ValueError(translate("impossible baudrate"));
|
||||
} else {
|
||||
uint32_t divider = 40000000L / self->baudrate;
|
||||
uint16_t prediv = MIN(divider, SPI_CLKDIV_PRE + 1);
|
||||
uint16_t cntdiv = (divider / prediv) * 2; // cntdiv has to be even
|
||||
if (cntdiv > SPI_CLKCNT_N + 1 || cntdiv == 0 || prediv == 0) {
|
||||
mp_raise_ValueError(translate("impossible baudrate"));
|
||||
}
|
||||
self->baudrate = 80000000L / (prediv * cntdiv);
|
||||
spi_init_gpio(HSPI, SPI_CLK_USE_DIV);
|
||||
spi_clock(HSPI, prediv, cntdiv);
|
||||
}
|
||||
// TODO: Make the byte order configurable too (discuss param names)
|
||||
spi_tx_byte_order(HSPI, SPI_BYTE_ORDER_HIGH_TO_LOW);
|
||||
spi_rx_byte_order(HSPI, SPI_BYTE_ORDER_HIGH_TO_LOW);
|
||||
CLEAR_PERI_REG_MASK(SPI_USER(HSPI), SPI_FLASH_MODE | SPI_USR_MISO |
|
||||
SPI_USR_ADDR | SPI_USR_COMMAND | SPI_USR_DUMMY);
|
||||
// Clear Dual or Quad lines transmission mode
|
||||
CLEAR_PERI_REG_MASK(SPI_CTRL(HSPI), SPI_QIO_MODE | SPI_DIO_MODE |
|
||||
SPI_DOUT_MODE | SPI_QOUT_MODE);
|
||||
spi_mode(HSPI, self->phase, self->polarity);
|
||||
}
|
||||
|
||||
mp_obj_t machine_hspi_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||
// args[0] holds the id of the peripheral
|
||||
if (args[0] != MP_OBJ_NEW_SMALL_INT(1)) {
|
||||
// FlashROM is on SPI0, so far we don't support its usage
|
||||
mp_raise_ValueError(NULL);
|
||||
}
|
||||
|
||||
machine_hspi_obj_t *self = m_new_obj(machine_hspi_obj_t);
|
||||
self->base.type = &machine_hspi_type;
|
||||
// set defaults
|
||||
self->baudrate = 80000000L;
|
||||
self->polarity = 0;
|
||||
self->phase = 0;
|
||||
mp_map_t kw_args;
|
||||
mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
|
||||
machine_hspi_init((mp_obj_base_t*)self, n_args - 1, args + 1, &kw_args);
|
||||
return MP_OBJ_FROM_PTR(self);
|
||||
}
|
||||
|
||||
STATIC const mp_machine_spi_p_t machine_hspi_p = {
|
||||
.init = machine_hspi_init,
|
||||
.transfer = machine_hspi_transfer,
|
||||
};
|
||||
|
||||
const mp_obj_type_t machine_hspi_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_HSPI,
|
||||
.print = machine_hspi_print,
|
||||
.make_new = mp_machine_spi_make_new, // delegate to master constructor
|
||||
.protocol = &machine_hspi_p,
|
||||
.locals_dict = (mp_obj_dict_t*)&mp_machine_spi_locals_dict,
|
||||
};
|
||||
|
||||
#endif // MICROPY_PY_MACHINE_SPI
|
@ -1,520 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014, 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "etshal.h"
|
||||
#include "c_types.h"
|
||||
#include "user_interface.h"
|
||||
#include "gpio.h"
|
||||
|
||||
#include "py/runtime.h"
|
||||
#include "py/gc.h"
|
||||
#include "py/mphal.h"
|
||||
#include "extmod/virtpin.h"
|
||||
#include "modmachine.h"
|
||||
|
||||
#include "supervisor/shared/translate.h"
|
||||
|
||||
#define GET_TRIGGER(phys_port) \
|
||||
GPIO_PIN_INT_TYPE_GET(GPIO_REG_READ(GPIO_PIN_ADDR(phys_port)))
|
||||
#define SET_TRIGGER(phys_port, trig) \
|
||||
(GPIO_REG_WRITE(GPIO_PIN_ADDR(phys_port), \
|
||||
(GPIO_REG_READ(GPIO_PIN_ADDR(phys_port)) & ~GPIO_PIN_INT_TYPE_MASK) \
|
||||
| GPIO_PIN_INT_TYPE_SET(trig))) \
|
||||
|
||||
#define GPIO_MODE_INPUT (0)
|
||||
#define GPIO_MODE_OUTPUT (1)
|
||||
#define GPIO_MODE_OPEN_DRAIN (2) // synthesised
|
||||
#define GPIO_PULL_NONE (0)
|
||||
#define GPIO_PULL_UP (1)
|
||||
// Removed in SDK 1.1.0
|
||||
//#define GPIO_PULL_DOWN (2)
|
||||
|
||||
typedef struct _pin_irq_obj_t {
|
||||
mp_obj_base_t base;
|
||||
uint16_t phys_port;
|
||||
} pin_irq_obj_t;
|
||||
|
||||
const pyb_pin_obj_t pyb_pin_obj[16 + 1] = {
|
||||
{{&pyb_pin_type}, 0, FUNC_GPIO0, PERIPHS_IO_MUX_GPIO0_U},
|
||||
{{&pyb_pin_type}, 1, FUNC_GPIO1, PERIPHS_IO_MUX_U0TXD_U},
|
||||
{{&pyb_pin_type}, 2, FUNC_GPIO2, PERIPHS_IO_MUX_GPIO2_U},
|
||||
{{&pyb_pin_type}, 3, FUNC_GPIO3, PERIPHS_IO_MUX_U0RXD_U},
|
||||
{{&pyb_pin_type}, 4, FUNC_GPIO4, PERIPHS_IO_MUX_GPIO4_U},
|
||||
{{&pyb_pin_type}, 5, FUNC_GPIO5, PERIPHS_IO_MUX_GPIO5_U},
|
||||
{{NULL}, 0, 0, 0},
|
||||
{{NULL}, 0, 0, 0},
|
||||
{{NULL}, 0, 0, 0},
|
||||
{{&pyb_pin_type}, 9, FUNC_GPIO9, PERIPHS_IO_MUX_SD_DATA2_U},
|
||||
{{&pyb_pin_type}, 10, FUNC_GPIO10, PERIPHS_IO_MUX_SD_DATA3_U},
|
||||
{{NULL}, 0, 0, 0},
|
||||
{{&pyb_pin_type}, 12, FUNC_GPIO12, PERIPHS_IO_MUX_MTDI_U},
|
||||
{{&pyb_pin_type}, 13, FUNC_GPIO13, PERIPHS_IO_MUX_MTCK_U},
|
||||
{{&pyb_pin_type}, 14, FUNC_GPIO14, PERIPHS_IO_MUX_MTMS_U},
|
||||
{{&pyb_pin_type}, 15, FUNC_GPIO15, PERIPHS_IO_MUX_MTDO_U},
|
||||
// GPIO16 is special, belongs to different register set, and
|
||||
// otherwise handled specially.
|
||||
{{&pyb_pin_type}, 16, -1, -1},
|
||||
};
|
||||
|
||||
STATIC uint8_t pin_mode[16 + 1];
|
||||
|
||||
// forward declaration
|
||||
STATIC const pin_irq_obj_t pin_irq_obj[16];
|
||||
|
||||
// whether the irq is hard or soft
|
||||
STATIC bool pin_irq_is_hard[16];
|
||||
|
||||
void pin_init0(void) {
|
||||
ETS_GPIO_INTR_DISABLE();
|
||||
ETS_GPIO_INTR_ATTACH(pin_intr_handler_iram, NULL);
|
||||
// disable all interrupts
|
||||
memset(&MP_STATE_PORT(pin_irq_handler)[0], 0, 16 * sizeof(mp_obj_t));
|
||||
memset(pin_irq_is_hard, 0, sizeof(pin_irq_is_hard));
|
||||
for (int p = 0; p < 16; ++p) {
|
||||
GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, 1 << p);
|
||||
SET_TRIGGER(p, 0);
|
||||
}
|
||||
ETS_GPIO_INTR_ENABLE();
|
||||
}
|
||||
|
||||
void pin_intr_handler(uint32_t status) {
|
||||
mp_sched_lock();
|
||||
gc_lock();
|
||||
status &= 0xffff;
|
||||
for (int p = 0; status; ++p, status >>= 1) {
|
||||
if (status & 1) {
|
||||
mp_obj_t handler = MP_STATE_PORT(pin_irq_handler)[p];
|
||||
if (handler != MP_OBJ_NULL) {
|
||||
if (pin_irq_is_hard[p]) {
|
||||
mp_call_function_1_protected(handler, MP_OBJ_FROM_PTR(&pyb_pin_obj[p]));
|
||||
} else {
|
||||
mp_sched_schedule(handler, MP_OBJ_FROM_PTR(&pyb_pin_obj[p]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
gc_unlock();
|
||||
mp_sched_unlock();
|
||||
}
|
||||
|
||||
pyb_pin_obj_t *mp_obj_get_pin_obj(mp_obj_t pin_in) {
|
||||
if (mp_obj_get_type(pin_in) != &pyb_pin_type) {
|
||||
mp_raise_ValueError(translate("expecting a pin"));
|
||||
}
|
||||
pyb_pin_obj_t *self = pin_in;
|
||||
return self;
|
||||
}
|
||||
|
||||
uint mp_obj_get_pin(mp_obj_t pin_in) {
|
||||
return mp_obj_get_pin_obj(pin_in)->phys_port;
|
||||
}
|
||||
|
||||
void mp_hal_pin_input(mp_hal_pin_obj_t pin_id) {
|
||||
pin_mode[pin_id] = GPIO_MODE_INPUT;
|
||||
if (pin_id == 16) {
|
||||
WRITE_PERI_REG(PAD_XPD_DCDC_CONF, (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | 1);
|
||||
WRITE_PERI_REG(RTC_GPIO_CONF, READ_PERI_REG(RTC_GPIO_CONF) & ~1);
|
||||
WRITE_PERI_REG(RTC_GPIO_ENABLE, (READ_PERI_REG(RTC_GPIO_ENABLE) & ~1)); // input
|
||||
} else {
|
||||
const pyb_pin_obj_t *self = &pyb_pin_obj[pin_id];
|
||||
PIN_FUNC_SELECT(self->periph, self->func);
|
||||
PIN_PULLUP_DIS(self->periph);
|
||||
gpio_output_set(0, 0, 0, 1 << self->phys_port);
|
||||
}
|
||||
}
|
||||
|
||||
void mp_hal_pin_output(mp_hal_pin_obj_t pin_id) {
|
||||
pin_mode[pin_id] = GPIO_MODE_OUTPUT;
|
||||
if (pin_id == 16) {
|
||||
WRITE_PERI_REG(PAD_XPD_DCDC_CONF, (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | 1);
|
||||
WRITE_PERI_REG(RTC_GPIO_CONF, READ_PERI_REG(RTC_GPIO_CONF) & ~1);
|
||||
WRITE_PERI_REG(RTC_GPIO_ENABLE, (READ_PERI_REG(RTC_GPIO_ENABLE) & ~1) | 1); // output
|
||||
} else {
|
||||
const pyb_pin_obj_t *self = &pyb_pin_obj[pin_id];
|
||||
PIN_FUNC_SELECT(self->periph, self->func);
|
||||
PIN_PULLUP_DIS(self->periph);
|
||||
gpio_output_set(0, 0, 1 << self->phys_port, 0);
|
||||
}
|
||||
}
|
||||
|
||||
void mp_hal_pin_open_drain(mp_hal_pin_obj_t pin_id) {
|
||||
const pyb_pin_obj_t *pin = &pyb_pin_obj[pin_id];
|
||||
|
||||
if (pin->phys_port == 16) {
|
||||
// configure GPIO16 as input with output register holding 0
|
||||
WRITE_PERI_REG(PAD_XPD_DCDC_CONF, (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | 1);
|
||||
WRITE_PERI_REG(RTC_GPIO_CONF, READ_PERI_REG(RTC_GPIO_CONF) & ~1);
|
||||
WRITE_PERI_REG(RTC_GPIO_ENABLE, (READ_PERI_REG(RTC_GPIO_ENABLE) & ~1)); // input
|
||||
WRITE_PERI_REG(RTC_GPIO_OUT, (READ_PERI_REG(RTC_GPIO_OUT) & ~1)); // out=0
|
||||
return;
|
||||
}
|
||||
|
||||
ETS_GPIO_INTR_DISABLE();
|
||||
PIN_FUNC_SELECT(pin->periph, pin->func);
|
||||
GPIO_REG_WRITE(GPIO_PIN_ADDR(GPIO_ID_PIN(pin->phys_port)),
|
||||
GPIO_REG_READ(GPIO_PIN_ADDR(GPIO_ID_PIN(pin->phys_port)))
|
||||
| GPIO_PIN_PAD_DRIVER_SET(GPIO_PAD_DRIVER_ENABLE)); // open drain
|
||||
GPIO_REG_WRITE(GPIO_ENABLE_ADDRESS,
|
||||
GPIO_REG_READ(GPIO_ENABLE_ADDRESS) | (1 << pin->phys_port));
|
||||
ETS_GPIO_INTR_ENABLE();
|
||||
}
|
||||
|
||||
int pin_get(uint pin) {
|
||||
if (pin == 16) {
|
||||
return READ_PERI_REG(RTC_GPIO_IN_DATA) & 1;
|
||||
}
|
||||
return GPIO_INPUT_GET(pin);
|
||||
}
|
||||
|
||||
void pin_set(uint pin, int value) {
|
||||
if (pin == 16) {
|
||||
int out_en = (pin_mode[pin] == GPIO_MODE_OUTPUT);
|
||||
WRITE_PERI_REG(PAD_XPD_DCDC_CONF, (READ_PERI_REG(PAD_XPD_DCDC_CONF) & 0xffffffbc) | 1);
|
||||
WRITE_PERI_REG(RTC_GPIO_CONF, READ_PERI_REG(RTC_GPIO_CONF) & ~1);
|
||||
WRITE_PERI_REG(RTC_GPIO_ENABLE, (READ_PERI_REG(RTC_GPIO_ENABLE) & ~1) | out_en);
|
||||
WRITE_PERI_REG(RTC_GPIO_OUT, (READ_PERI_REG(RTC_GPIO_OUT) & ~1) | value);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t enable = 0;
|
||||
uint32_t disable = 0;
|
||||
switch (pin_mode[pin]) {
|
||||
case GPIO_MODE_INPUT:
|
||||
value = -1;
|
||||
disable = 1;
|
||||
break;
|
||||
|
||||
case GPIO_MODE_OUTPUT:
|
||||
enable = 1;
|
||||
break;
|
||||
|
||||
case GPIO_MODE_OPEN_DRAIN:
|
||||
if (value == -1) {
|
||||
return;
|
||||
} else if (value == 0) {
|
||||
enable = 1;
|
||||
} else {
|
||||
value = -1;
|
||||
disable = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
enable <<= pin;
|
||||
disable <<= pin;
|
||||
if (value == -1) {
|
||||
gpio_output_set(0, 0, enable, disable);
|
||||
} else {
|
||||
gpio_output_set(value << pin, (1 - value) << pin, enable, disable);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void pyb_pin_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pyb_pin_obj_t *self = self_in;
|
||||
|
||||
// pin name
|
||||
mp_printf(print, "Pin(%u)", self->phys_port);
|
||||
}
|
||||
|
||||
// pin.init(mode, pull=None, *, value)
|
||||
STATIC mp_obj_t pyb_pin_obj_init_helper(pyb_pin_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
enum { ARG_mode, ARG_pull, ARG_value };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_mode, MP_ARG_REQUIRED | MP_ARG_INT },
|
||||
{ MP_QSTR_pull, MP_ARG_OBJ, {.u_obj = mp_const_none}},
|
||||
{ MP_QSTR_value, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL}},
|
||||
};
|
||||
|
||||
// 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);
|
||||
|
||||
// get io mode
|
||||
uint mode = args[ARG_mode].u_int;
|
||||
|
||||
// get pull mode
|
||||
uint pull = GPIO_PULL_NONE;
|
||||
if (args[ARG_pull].u_obj != mp_const_none) {
|
||||
pull = mp_obj_get_int(args[ARG_pull].u_obj);
|
||||
}
|
||||
|
||||
// get initial value
|
||||
int value;
|
||||
if (args[ARG_value].u_obj == MP_OBJ_NULL) {
|
||||
value = -1;
|
||||
} else {
|
||||
value = mp_obj_is_true(args[ARG_value].u_obj);
|
||||
}
|
||||
|
||||
// save the mode
|
||||
pin_mode[self->phys_port] = mode;
|
||||
|
||||
// configure the GPIO as requested
|
||||
if (self->phys_port == 16) {
|
||||
// only pull-down seems to be supported by the hardware, and
|
||||
// we only expose pull-up behaviour in software
|
||||
if (pull != GPIO_PULL_NONE) {
|
||||
mp_raise_ValueError(translate("Pin(16) doesn't support pull"));
|
||||
}
|
||||
} else {
|
||||
PIN_FUNC_SELECT(self->periph, self->func);
|
||||
#if 0
|
||||
// Removed in SDK 1.1.0
|
||||
if ((pull & GPIO_PULL_DOWN) == 0) {
|
||||
PIN_PULLDWN_DIS(self->periph);
|
||||
}
|
||||
#endif
|
||||
if ((pull & GPIO_PULL_UP) == 0) {
|
||||
PIN_PULLUP_DIS(self->periph);
|
||||
}
|
||||
#if 0
|
||||
if ((pull & GPIO_PULL_DOWN) != 0) {
|
||||
PIN_PULLDWN_EN(self->periph);
|
||||
}
|
||||
#endif
|
||||
if ((pull & GPIO_PULL_UP) != 0) {
|
||||
PIN_PULLUP_EN(self->periph);
|
||||
}
|
||||
}
|
||||
|
||||
pin_set(self->phys_port, value);
|
||||
|
||||
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);
|
||||
|
||||
// get the wanted pin object
|
||||
int wanted_pin = mp_obj_get_int(args[0]);
|
||||
pyb_pin_obj_t *pin = NULL;
|
||||
if (0 <= wanted_pin && wanted_pin < MP_ARRAY_SIZE(pyb_pin_obj)) {
|
||||
pin = (pyb_pin_obj_t*)&pyb_pin_obj[wanted_pin];
|
||||
}
|
||||
if (pin == NULL || pin->base.type == NULL) {
|
||||
mp_raise_ValueError(translate("invalid pin"));
|
||||
}
|
||||
|
||||
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);
|
||||
pyb_pin_obj_init_helper(pin, n_args - 1, args + 1, &kw_args);
|
||||
}
|
||||
|
||||
return (mp_obj_t)pin;
|
||||
}
|
||||
|
||||
// fast method for getting/setting pin value
|
||||
STATIC mp_obj_t pyb_pin_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||
mp_arg_check_num(n_args, n_kw, 0, 1, false);
|
||||
pyb_pin_obj_t *self = self_in;
|
||||
if (n_args == 0) {
|
||||
// get pin
|
||||
return MP_OBJ_NEW_SMALL_INT(pin_get(self->phys_port));
|
||||
} else {
|
||||
// set pin
|
||||
pin_set(self->phys_port, mp_obj_is_true(args[0]));
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
||||
|
||||
// pin.init(mode, pull)
|
||||
STATIC mp_obj_t pyb_pin_obj_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
return pyb_pin_obj_init_helper(args[0], n_args - 1, args + 1, kw_args);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(pyb_pin_init_obj, 1, pyb_pin_obj_init);
|
||||
|
||||
// pin.value([value])
|
||||
STATIC mp_obj_t pyb_pin_value(size_t n_args, const mp_obj_t *args) {
|
||||
return pyb_pin_call(args[0], n_args - 1, 0, args + 1);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_pin_value_obj, 1, 2, pyb_pin_value);
|
||||
|
||||
STATIC mp_obj_t pyb_pin_off(mp_obj_t self_in) {
|
||||
pyb_pin_obj_t *self = self_in;
|
||||
pin_set(self->phys_port, 0);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_pin_off_obj, pyb_pin_off);
|
||||
|
||||
STATIC mp_obj_t pyb_pin_on(mp_obj_t self_in) {
|
||||
pyb_pin_obj_t *self = self_in;
|
||||
pin_set(self->phys_port, 1);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_pin_on_obj, pyb_pin_on);
|
||||
|
||||
// pin.irq(handler=None, trigger=IRQ_FALLING|IRQ_RISING, hard=False)
|
||||
STATIC mp_obj_t pyb_pin_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
enum { ARG_handler, ARG_trigger, ARG_hard };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_handler, MP_ARG_OBJ, {.u_obj = mp_const_none} },
|
||||
{ MP_QSTR_trigger, MP_ARG_INT, {.u_int = GPIO_PIN_INTR_POSEDGE | GPIO_PIN_INTR_NEGEDGE} },
|
||||
{ MP_QSTR_hard, MP_ARG_BOOL, {.u_bool = false} },
|
||||
};
|
||||
pyb_pin_obj_t *self = MP_OBJ_TO_PTR(pos_args[0]);
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
if (self->phys_port >= 16) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, translate("pin does not have IRQ capabilities")));
|
||||
}
|
||||
|
||||
if (n_args > 1 || kw_args->used != 0) {
|
||||
// configure irq
|
||||
mp_obj_t handler = args[ARG_handler].u_obj;
|
||||
uint32_t trigger = args[ARG_trigger].u_int;
|
||||
if (handler == mp_const_none) {
|
||||
handler = MP_OBJ_NULL;
|
||||
trigger = 0;
|
||||
}
|
||||
ETS_GPIO_INTR_DISABLE();
|
||||
MP_STATE_PORT(pin_irq_handler)[self->phys_port] = handler;
|
||||
pin_irq_is_hard[self->phys_port] = args[ARG_hard].u_bool;
|
||||
SET_TRIGGER(self->phys_port, trigger);
|
||||
GPIO_REG_WRITE(GPIO_STATUS_W1TC_ADDRESS, 1 << self->phys_port);
|
||||
ETS_GPIO_INTR_ENABLE();
|
||||
}
|
||||
|
||||
// return the irq object
|
||||
return MP_OBJ_FROM_PTR(&pin_irq_obj[self->phys_port]);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_pin_irq_obj, 1, pyb_pin_irq);
|
||||
|
||||
STATIC mp_uint_t pin_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode);
|
||||
STATIC mp_uint_t pin_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr_t arg, int *errcode) {
|
||||
(void)errcode;
|
||||
pyb_pin_obj_t *self = self_in;
|
||||
|
||||
switch (request) {
|
||||
case MP_PIN_READ: {
|
||||
return pin_get(self->phys_port);
|
||||
}
|
||||
case MP_PIN_WRITE: {
|
||||
pin_set(self->phys_port, arg);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
STATIC const mp_rom_map_elem_t pyb_pin_locals_dict_table[] = {
|
||||
// instance methods
|
||||
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&pyb_pin_init_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_value), MP_ROM_PTR(&pyb_pin_value_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_off), MP_ROM_PTR(&pyb_pin_off_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_on), MP_ROM_PTR(&pyb_pin_on_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_irq), MP_ROM_PTR(&pyb_pin_irq_obj) },
|
||||
|
||||
// class constants
|
||||
{ MP_ROM_QSTR(MP_QSTR_IN), MP_ROM_INT(GPIO_MODE_INPUT) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_OUT), MP_ROM_INT(GPIO_MODE_OUTPUT) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_OPEN_DRAIN), MP_ROM_INT(GPIO_MODE_OPEN_DRAIN) },
|
||||
{ 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) },
|
||||
|
||||
// IRQ triggers, can be or'd together
|
||||
{ MP_ROM_QSTR(MP_QSTR_IRQ_RISING), MP_ROM_INT(GPIO_PIN_INTR_POSEDGE) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_IRQ_FALLING), MP_ROM_INT(GPIO_PIN_INTR_NEGEDGE) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(pyb_pin_locals_dict, pyb_pin_locals_dict_table);
|
||||
|
||||
STATIC const mp_pin_p_t pin_pin_p = {
|
||||
.ioctl = pin_ioctl,
|
||||
};
|
||||
|
||||
const mp_obj_type_t pyb_pin_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_Pin,
|
||||
.print = pyb_pin_print,
|
||||
.make_new = mp_pin_make_new,
|
||||
.call = pyb_pin_call,
|
||||
.protocol = &pin_pin_p,
|
||||
.locals_dict = (mp_obj_dict_t*)&pyb_pin_locals_dict,
|
||||
};
|
||||
|
||||
/******************************************************************************/
|
||||
// Pin IRQ object
|
||||
|
||||
STATIC const mp_obj_type_t pin_irq_type;
|
||||
|
||||
STATIC const pin_irq_obj_t pin_irq_obj[16] = {
|
||||
{{&pin_irq_type}, 0},
|
||||
{{&pin_irq_type}, 1},
|
||||
{{&pin_irq_type}, 2},
|
||||
{{&pin_irq_type}, 3},
|
||||
{{&pin_irq_type}, 4},
|
||||
{{&pin_irq_type}, 5},
|
||||
{{&pin_irq_type}, 6},
|
||||
{{&pin_irq_type}, 7},
|
||||
{{&pin_irq_type}, 8},
|
||||
{{&pin_irq_type}, 9},
|
||||
{{&pin_irq_type}, 10},
|
||||
{{&pin_irq_type}, 11},
|
||||
{{&pin_irq_type}, 12},
|
||||
{{&pin_irq_type}, 13},
|
||||
{{&pin_irq_type}, 14},
|
||||
{{&pin_irq_type}, 15},
|
||||
};
|
||||
|
||||
STATIC mp_obj_t pin_irq_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||
pin_irq_obj_t *self = self_in;
|
||||
mp_arg_check_num(n_args, n_kw, 0, 0, false);
|
||||
pin_intr_handler(1 << self->phys_port);
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
STATIC mp_obj_t pin_irq_trigger(size_t n_args, const mp_obj_t *args) {
|
||||
pin_irq_obj_t *self = args[0];
|
||||
uint32_t orig_trig = GET_TRIGGER(self->phys_port);
|
||||
if (n_args == 2) {
|
||||
// set trigger
|
||||
SET_TRIGGER(self->phys_port, mp_obj_get_int(args[1]));
|
||||
}
|
||||
// return original trigger value
|
||||
return MP_OBJ_NEW_SMALL_INT(orig_trig);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pin_irq_trigger_obj, 1, 2, pin_irq_trigger);
|
||||
|
||||
STATIC const mp_rom_map_elem_t pin_irq_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_trigger), MP_ROM_PTR(&pin_irq_trigger_obj) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(pin_irq_locals_dict, pin_irq_locals_dict_table);
|
||||
|
||||
STATIC const mp_obj_type_t pin_irq_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_IRQ,
|
||||
.call = pin_irq_call,
|
||||
.locals_dict = (mp_obj_dict_t*)&pin_irq_locals_dict,
|
||||
};
|
@ -1,172 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 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 <stdint.h>
|
||||
|
||||
#include "esppwm.h"
|
||||
|
||||
#include "py/runtime.h"
|
||||
#include "modmachine.h"
|
||||
#include "supervisor/shared/translate.h"
|
||||
|
||||
typedef struct _pyb_pwm_obj_t {
|
||||
mp_obj_base_t base;
|
||||
pyb_pin_obj_t *pin;
|
||||
uint8_t active;
|
||||
uint8_t channel;
|
||||
} pyb_pwm_obj_t;
|
||||
|
||||
bool pwm_inited = false;
|
||||
|
||||
/******************************************************************************/
|
||||
// MicroPython bindings for PWM
|
||||
|
||||
STATIC void pyb_pwm_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pyb_pwm_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
mp_printf(print, "PWM(%u", self->pin->phys_port);
|
||||
if (self->active) {
|
||||
mp_printf(print, ", freq=%u, duty=%u",
|
||||
pwm_get_freq(self->channel), pwm_get_duty(self->channel));
|
||||
}
|
||||
mp_printf(print, ")");
|
||||
}
|
||||
|
||||
STATIC void pyb_pwm_init_helper(pyb_pwm_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
enum { ARG_freq, ARG_duty };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_freq, MP_ARG_INT, {.u_int = -1} },
|
||||
{ MP_QSTR_duty, MP_ARG_INT, {.u_int = -1} },
|
||||
};
|
||||
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);
|
||||
|
||||
int channel = pwm_add(self->pin->phys_port, self->pin->periph, self->pin->func);
|
||||
if (channel == -1) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
|
||||
translate("PWM not supported on pin %d"), self->pin->phys_port));
|
||||
}
|
||||
|
||||
self->channel = channel;
|
||||
self->active = 1;
|
||||
if (args[ARG_freq].u_int != -1) {
|
||||
pwm_set_freq(args[ARG_freq].u_int, self->channel);
|
||||
}
|
||||
if (args[ARG_duty].u_int != -1) {
|
||||
pwm_set_duty(args[ARG_duty].u_int, self->channel);
|
||||
}
|
||||
|
||||
pwm_start();
|
||||
}
|
||||
|
||||
STATIC mp_obj_t pyb_pwm_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);
|
||||
pyb_pin_obj_t *pin = mp_obj_get_pin_obj(args[0]);
|
||||
|
||||
// create PWM object from the given pin
|
||||
pyb_pwm_obj_t *self = m_new_obj(pyb_pwm_obj_t);
|
||||
self->base.type = &pyb_pwm_type;
|
||||
self->pin = pin;
|
||||
self->active = 0;
|
||||
self->channel = -1;
|
||||
|
||||
// start the PWM subsystem if it's not already running
|
||||
if (!pwm_inited) {
|
||||
pwm_init();
|
||||
pwm_inited = true;
|
||||
}
|
||||
|
||||
// start the PWM running for this channel
|
||||
mp_map_t kw_args;
|
||||
mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
|
||||
pyb_pwm_init_helper(self, n_args - 1, args + 1, &kw_args);
|
||||
|
||||
return MP_OBJ_FROM_PTR(self);
|
||||
}
|
||||
|
||||
STATIC mp_obj_t pyb_pwm_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
pyb_pwm_init_helper(args[0], n_args - 1, args + 1, kw_args);
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(pyb_pwm_init_obj, 1, pyb_pwm_init);
|
||||
|
||||
STATIC mp_obj_t pyb_pwm_deinit(mp_obj_t self_in) {
|
||||
pyb_pwm_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
pwm_delete(self->channel);
|
||||
self->active = 0;
|
||||
pwm_start();
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_pwm_deinit_obj, pyb_pwm_deinit);
|
||||
|
||||
STATIC mp_obj_t pyb_pwm_freq(size_t n_args, const mp_obj_t *args) {
|
||||
//pyb_pwm_obj_t *self = MP_OBJ_TO_PTR(args[0]);
|
||||
if (n_args == 1) {
|
||||
// get
|
||||
return MP_OBJ_NEW_SMALL_INT(pwm_get_freq(0));
|
||||
} else {
|
||||
// set
|
||||
pwm_set_freq(mp_obj_get_int(args[1]), 0);
|
||||
pwm_start();
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_pwm_freq_obj, 1, 2, pyb_pwm_freq);
|
||||
|
||||
STATIC mp_obj_t pyb_pwm_duty(size_t n_args, const mp_obj_t *args) {
|
||||
pyb_pwm_obj_t *self = MP_OBJ_TO_PTR(args[0]);
|
||||
if (!self->active) {
|
||||
pwm_add(self->pin->phys_port, self->pin->periph, self->pin->func);
|
||||
self->active = 1;
|
||||
}
|
||||
if (n_args == 1) {
|
||||
// get
|
||||
return MP_OBJ_NEW_SMALL_INT(pwm_get_duty(self->channel));
|
||||
} else {
|
||||
// set
|
||||
pwm_set_duty(mp_obj_get_int(args[1]), self->channel);
|
||||
pwm_start();
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_pwm_duty_obj, 1, 2, pyb_pwm_duty);
|
||||
|
||||
STATIC const mp_rom_map_elem_t pyb_pwm_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&pyb_pwm_init_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&pyb_pwm_deinit_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_freq), MP_ROM_PTR(&pyb_pwm_freq_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_duty), MP_ROM_PTR(&pyb_pwm_duty_obj) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(pyb_pwm_locals_dict, pyb_pwm_locals_dict_table);
|
||||
|
||||
const mp_obj_type_t pyb_pwm_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_PWM,
|
||||
.print = pyb_pwm_print,
|
||||
.make_new = pyb_pwm_make_new,
|
||||
.locals_dict = (mp_obj_dict_t*)&pyb_pwm_locals_dict,
|
||||
};
|
@ -1,271 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 Josef Gajdusek
|
||||
*
|
||||
* 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 "lib/timeutils/timeutils.h"
|
||||
#include "supervisor/shared/translate.h"
|
||||
#include "user_interface.h"
|
||||
#include "modmachine.h"
|
||||
|
||||
typedef struct _pyb_rtc_obj_t {
|
||||
mp_obj_base_t base;
|
||||
} pyb_rtc_obj_t;
|
||||
|
||||
#define MEM_MAGIC 0x75507921
|
||||
#define MEM_DELTA_ADDR 64
|
||||
#define MEM_CAL_ADDR (MEM_DELTA_ADDR + 2)
|
||||
#define MEM_USER_MAGIC_ADDR (MEM_CAL_ADDR + 1)
|
||||
#define MEM_USER_LEN_ADDR (MEM_USER_MAGIC_ADDR + 1)
|
||||
#define MEM_USER_DATA_ADDR (MEM_USER_LEN_ADDR + 1)
|
||||
#define MEM_USER_MAXLEN (512 - (MEM_USER_DATA_ADDR - MEM_DELTA_ADDR) * 4)
|
||||
|
||||
// singleton RTC object
|
||||
STATIC const pyb_rtc_obj_t pyb_rtc_obj = {{&pyb_rtc_type}};
|
||||
|
||||
// ALARM0 state
|
||||
uint32_t pyb_rtc_alarm0_wake; // see MACHINE_WAKE_xxx constants
|
||||
uint64_t pyb_rtc_alarm0_expiry; // in microseconds
|
||||
|
||||
// RTC overflow checking
|
||||
STATIC uint32_t rtc_last_ticks;
|
||||
|
||||
void mp_hal_rtc_init(void) {
|
||||
uint32_t magic;
|
||||
|
||||
system_rtc_mem_read(MEM_USER_MAGIC_ADDR, &magic, sizeof(magic));
|
||||
if (magic != MEM_MAGIC) {
|
||||
magic = MEM_MAGIC;
|
||||
system_rtc_mem_write(MEM_USER_MAGIC_ADDR, &magic, sizeof(magic));
|
||||
uint32_t cal = system_rtc_clock_cali_proc();
|
||||
int64_t delta = 0;
|
||||
system_rtc_mem_write(MEM_CAL_ADDR, &cal, sizeof(cal));
|
||||
system_rtc_mem_write(MEM_DELTA_ADDR, &delta, sizeof(delta));
|
||||
uint32_t len = 0;
|
||||
system_rtc_mem_write(MEM_USER_LEN_ADDR, &len, sizeof(len));
|
||||
}
|
||||
// system_get_rtc_time() is always 0 after reset/deepsleep
|
||||
rtc_last_ticks = system_get_rtc_time();
|
||||
|
||||
// reset ALARM0 state
|
||||
pyb_rtc_alarm0_wake = 0;
|
||||
pyb_rtc_alarm0_expiry = 0;
|
||||
}
|
||||
|
||||
STATIC mp_obj_t pyb_rtc_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||
// check arguments
|
||||
mp_arg_check_num(n_args, n_kw, 0, 0, false);
|
||||
|
||||
// return constant object
|
||||
return (mp_obj_t)&pyb_rtc_obj;
|
||||
}
|
||||
|
||||
void pyb_rtc_set_us_since_2000(uint64_t nowus) {
|
||||
uint32_t cal = system_rtc_clock_cali_proc();
|
||||
// Save RTC ticks for overflow detection.
|
||||
rtc_last_ticks = system_get_rtc_time();
|
||||
int64_t delta = nowus - (((uint64_t)rtc_last_ticks * cal) >> 12);
|
||||
|
||||
// As the calibration value jitters quite a bit, to make the
|
||||
// clock at least somewhat practically usable, we need to store it
|
||||
system_rtc_mem_write(MEM_CAL_ADDR, &cal, sizeof(cal));
|
||||
system_rtc_mem_write(MEM_DELTA_ADDR, &delta, sizeof(delta));
|
||||
};
|
||||
|
||||
uint64_t pyb_rtc_get_us_since_2000() {
|
||||
uint32_t cal;
|
||||
int64_t delta;
|
||||
uint32_t rtc_ticks;
|
||||
|
||||
system_rtc_mem_read(MEM_CAL_ADDR, &cal, sizeof(cal));
|
||||
system_rtc_mem_read(MEM_DELTA_ADDR, &delta, sizeof(delta));
|
||||
|
||||
// ESP-SDK system_get_rtc_time() only returns uint32 and therefore
|
||||
// overflow about every 7:45h. Thus, we have to check for
|
||||
// overflow and handle it.
|
||||
rtc_ticks = system_get_rtc_time();
|
||||
if (rtc_ticks < rtc_last_ticks) {
|
||||
// Adjust delta because of RTC overflow.
|
||||
delta += (uint64_t)cal << 20;
|
||||
system_rtc_mem_write(MEM_DELTA_ADDR, &delta, sizeof(delta));
|
||||
}
|
||||
rtc_last_ticks = rtc_ticks;
|
||||
|
||||
return (((uint64_t)rtc_ticks * cal) >> 12) + delta;
|
||||
};
|
||||
|
||||
void rtc_prepare_deepsleep(uint64_t sleep_us) {
|
||||
// RTC time will reset at wake up. Let's be preared for this.
|
||||
int64_t delta = pyb_rtc_get_us_since_2000() + sleep_us;
|
||||
system_rtc_mem_write(MEM_DELTA_ADDR, &delta, sizeof(delta));
|
||||
}
|
||||
|
||||
STATIC mp_obj_t pyb_rtc_datetime(size_t n_args, const mp_obj_t *args) {
|
||||
if (n_args == 1) {
|
||||
// Get time
|
||||
uint64_t msecs = pyb_rtc_get_us_since_2000() / 1000;
|
||||
|
||||
timeutils_struct_time_t tm;
|
||||
timeutils_seconds_since_2000_to_struct_time(msecs / 1000, &tm);
|
||||
|
||||
mp_obj_t tuple[8] = {
|
||||
mp_obj_new_int(tm.tm_year),
|
||||
mp_obj_new_int(tm.tm_mon),
|
||||
mp_obj_new_int(tm.tm_mday),
|
||||
mp_obj_new_int(tm.tm_wday),
|
||||
mp_obj_new_int(tm.tm_hour),
|
||||
mp_obj_new_int(tm.tm_min),
|
||||
mp_obj_new_int(tm.tm_sec),
|
||||
mp_obj_new_int(msecs % 1000)
|
||||
};
|
||||
|
||||
return mp_obj_new_tuple(8, tuple);
|
||||
} else {
|
||||
// Set time
|
||||
mp_obj_t *items;
|
||||
mp_obj_get_array_fixed_n(args[1], 8, &items);
|
||||
|
||||
pyb_rtc_set_us_since_2000(
|
||||
((uint64_t)timeutils_seconds_since_2000(
|
||||
mp_obj_get_int(items[0]),
|
||||
mp_obj_get_int(items[1]),
|
||||
mp_obj_get_int(items[2]),
|
||||
mp_obj_get_int(items[4]),
|
||||
mp_obj_get_int(items[5]),
|
||||
mp_obj_get_int(items[6])) * 1000 + mp_obj_get_int(items[7])) * 1000);
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_rtc_datetime_obj, 1, 2, pyb_rtc_datetime);
|
||||
|
||||
STATIC mp_obj_t pyb_rtc_memory(size_t n_args, const mp_obj_t *args) {
|
||||
uint8_t rtcram[MEM_USER_MAXLEN];
|
||||
uint32_t len;
|
||||
|
||||
if (n_args == 1) {
|
||||
// read RTC memory
|
||||
|
||||
system_rtc_mem_read(MEM_USER_LEN_ADDR, &len, sizeof(len));
|
||||
system_rtc_mem_read(MEM_USER_DATA_ADDR, rtcram, (len + 3) & ~3);
|
||||
|
||||
return mp_obj_new_bytes(rtcram, len);
|
||||
} else {
|
||||
// write RTC memory
|
||||
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(args[1], &bufinfo, MP_BUFFER_READ);
|
||||
|
||||
if (bufinfo.len > MEM_USER_MAXLEN) {
|
||||
mp_raise_ValueError(translate("buffer too long"));
|
||||
}
|
||||
|
||||
len = bufinfo.len;
|
||||
system_rtc_mem_write(MEM_USER_LEN_ADDR, &len, sizeof(len));
|
||||
|
||||
int i = 0;
|
||||
for (; i < bufinfo.len; i++) {
|
||||
rtcram[i] = ((uint8_t *)bufinfo.buf)[i];
|
||||
}
|
||||
|
||||
system_rtc_mem_write(MEM_USER_DATA_ADDR, rtcram, (len + 3) & ~3);
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_rtc_memory_obj, 1, 2, pyb_rtc_memory);
|
||||
|
||||
STATIC mp_obj_t pyb_rtc_alarm(mp_obj_t self_in, mp_obj_t alarm_id, mp_obj_t time_in) {
|
||||
(void)self_in; // unused
|
||||
|
||||
// check we want alarm0
|
||||
if (mp_obj_get_int(alarm_id) != 0) {
|
||||
mp_raise_ValueError(translate("invalid alarm"));
|
||||
}
|
||||
|
||||
// set expiry time (in microseconds)
|
||||
pyb_rtc_alarm0_expiry = pyb_rtc_get_us_since_2000() + (uint64_t)mp_obj_get_int(time_in) * 1000;
|
||||
|
||||
return mp_const_none;
|
||||
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_3(pyb_rtc_alarm_obj, pyb_rtc_alarm);
|
||||
|
||||
STATIC mp_obj_t pyb_rtc_alarm_left(size_t n_args, const mp_obj_t *args) {
|
||||
// check we want alarm0
|
||||
if (n_args > 1 && mp_obj_get_int(args[1]) != 0) {
|
||||
mp_raise_ValueError(translate("invalid alarm"));
|
||||
}
|
||||
|
||||
uint64_t now = pyb_rtc_get_us_since_2000();
|
||||
if (pyb_rtc_alarm0_expiry <= now) {
|
||||
return MP_OBJ_NEW_SMALL_INT(0);
|
||||
} else {
|
||||
return mp_obj_new_int((pyb_rtc_alarm0_expiry - now) / 1000);
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_rtc_alarm_left_obj, 1, 2, pyb_rtc_alarm_left);
|
||||
|
||||
STATIC mp_obj_t pyb_rtc_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
enum { ARG_trigger, ARG_wake };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_trigger, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_wake, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
|
||||
};
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
// check we want alarm0
|
||||
if (args[ARG_trigger].u_int != 0) {
|
||||
mp_raise_ValueError(translate("invalid alarm"));
|
||||
}
|
||||
|
||||
// set the wake value
|
||||
pyb_rtc_alarm0_wake = args[ARG_wake].u_int;
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(pyb_rtc_irq_obj, 1, pyb_rtc_irq);
|
||||
|
||||
STATIC const mp_rom_map_elem_t pyb_rtc_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_datetime), MP_ROM_PTR(&pyb_rtc_datetime_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_memory), MP_ROM_PTR(&pyb_rtc_memory_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_alarm), MP_ROM_PTR(&pyb_rtc_alarm_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_alarm_left), MP_ROM_PTR(&pyb_rtc_alarm_left_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_irq), MP_ROM_PTR(&pyb_rtc_irq_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_ALARM0), MP_ROM_INT(0) },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(pyb_rtc_locals_dict, pyb_rtc_locals_dict_table);
|
||||
|
||||
const mp_obj_type_t pyb_rtc_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_RTC,
|
||||
.make_new = pyb_rtc_make_new,
|
||||
.locals_dict = (mp_obj_dict_t*)&pyb_rtc_locals_dict,
|
||||
};
|
@ -1,300 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 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 <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ets_sys.h"
|
||||
#include "uart.h"
|
||||
|
||||
#include "py/runtime.h"
|
||||
#include "py/stream.h"
|
||||
#include "py/mperrno.h"
|
||||
#include "supervisor/shared/translate.h"
|
||||
#include "modmachine.h"
|
||||
|
||||
// UartDev is defined and initialized in rom code.
|
||||
extern UartDevice UartDev;
|
||||
|
||||
typedef struct _pyb_uart_obj_t {
|
||||
mp_obj_base_t base;
|
||||
uint8_t uart_id;
|
||||
uint8_t bits;
|
||||
uint8_t parity;
|
||||
uint8_t stop;
|
||||
uint32_t baudrate;
|
||||
uint16_t timeout; // timeout waiting for first char (in ms)
|
||||
uint16_t timeout_char; // timeout waiting between chars (in ms)
|
||||
} pyb_uart_obj_t;
|
||||
|
||||
STATIC const char *_parity_name[] = {"None", "1", "0"};
|
||||
|
||||
/******************************************************************************/
|
||||
// MicroPython bindings for UART
|
||||
|
||||
STATIC void pyb_uart_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
pyb_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
mp_printf(print, "UART(%u, baudrate=%u, bits=%u, parity=%s, stop=%u, timeout=%u, timeout_char=%u)",
|
||||
self->uart_id, self->baudrate, self->bits, _parity_name[self->parity],
|
||||
self->stop, self->timeout, self->timeout_char);
|
||||
}
|
||||
|
||||
STATIC void pyb_uart_init_helper(pyb_uart_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
enum { ARG_baudrate, ARG_bits, ARG_parity, ARG_stop, ARG_timeout, ARG_timeout_char };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_baudrate, MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_bits, MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_parity, MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||
{ MP_QSTR_stop, MP_ARG_INT, {.u_int = 0} },
|
||||
//{ MP_QSTR_tx, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||
//{ MP_QSTR_rx, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = MP_OBJ_NULL} },
|
||||
{ MP_QSTR_timeout, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
|
||||
{ MP_QSTR_timeout_char, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
|
||||
};
|
||||
mp_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 baudrate
|
||||
if (args[ARG_baudrate].u_int > 0) {
|
||||
self->baudrate = args[ARG_baudrate].u_int;
|
||||
UartDev.baut_rate = self->baudrate; // Sic!
|
||||
}
|
||||
|
||||
// set data bits
|
||||
switch (args[ARG_bits].u_int) {
|
||||
case 0:
|
||||
break;
|
||||
case 5:
|
||||
UartDev.data_bits = UART_FIVE_BITS;
|
||||
self->bits = 5;
|
||||
break;
|
||||
case 6:
|
||||
UartDev.data_bits = UART_SIX_BITS;
|
||||
self->bits = 6;
|
||||
break;
|
||||
case 7:
|
||||
UartDev.data_bits = UART_SEVEN_BITS;
|
||||
self->bits = 7;
|
||||
break;
|
||||
case 8:
|
||||
UartDev.data_bits = UART_EIGHT_BITS;
|
||||
self->bits = 8;
|
||||
break;
|
||||
default:
|
||||
mp_raise_ValueError(translate("invalid data bits"));
|
||||
break;
|
||||
}
|
||||
|
||||
// set parity
|
||||
if (args[ARG_parity].u_obj != MP_OBJ_NULL) {
|
||||
if (args[ARG_parity].u_obj == mp_const_none) {
|
||||
UartDev.parity = UART_NONE_BITS;
|
||||
UartDev.exist_parity = UART_STICK_PARITY_DIS;
|
||||
self->parity = 0;
|
||||
} else {
|
||||
mp_int_t parity = mp_obj_get_int(args[ARG_parity].u_obj);
|
||||
UartDev.exist_parity = UART_STICK_PARITY_EN;
|
||||
if (parity & 1) {
|
||||
UartDev.parity = UART_ODD_BITS;
|
||||
self->parity = 1;
|
||||
} else {
|
||||
UartDev.parity = UART_EVEN_BITS;
|
||||
self->parity = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set stop bits
|
||||
switch (args[ARG_stop].u_int) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
UartDev.stop_bits = UART_ONE_STOP_BIT;
|
||||
self->stop = 1;
|
||||
break;
|
||||
case 2:
|
||||
UartDev.stop_bits = UART_TWO_STOP_BIT;
|
||||
self->stop = 2;
|
||||
break;
|
||||
default:
|
||||
mp_raise_ValueError(translate("invalid stop bits"));
|
||||
break;
|
||||
}
|
||||
|
||||
// set timeout
|
||||
self->timeout = args[ARG_timeout].u_int;
|
||||
|
||||
// set timeout_char
|
||||
// make sure it is at least as long as a whole character (13 bits to be safe)
|
||||
self->timeout_char = args[ARG_timeout_char].u_int;
|
||||
uint32_t min_timeout_char = 13000 / self->baudrate + 1;
|
||||
if (self->timeout_char < min_timeout_char) {
|
||||
self->timeout_char = min_timeout_char;
|
||||
}
|
||||
|
||||
// setup
|
||||
uart_setup(self->uart_id);
|
||||
}
|
||||
|
||||
STATIC mp_obj_t pyb_uart_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);
|
||||
|
||||
// get uart id
|
||||
mp_int_t uart_id = mp_obj_get_int(args[0]);
|
||||
if (uart_id != 0 && uart_id != 1) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, translate("UART(%d) does not exist"), uart_id));
|
||||
}
|
||||
|
||||
// create instance
|
||||
pyb_uart_obj_t *self = m_new_obj(pyb_uart_obj_t);
|
||||
self->base.type = &pyb_uart_type;
|
||||
self->uart_id = uart_id;
|
||||
self->baudrate = 115200;
|
||||
self->bits = 8;
|
||||
self->parity = 0;
|
||||
self->stop = 1;
|
||||
self->timeout = 0;
|
||||
self->timeout_char = 0;
|
||||
|
||||
// init the peripheral
|
||||
mp_map_t kw_args;
|
||||
mp_map_init_fixed_table(&kw_args, n_kw, args + n_args);
|
||||
pyb_uart_init_helper(self, n_args - 1, args + 1, &kw_args);
|
||||
|
||||
return MP_OBJ_FROM_PTR(self);
|
||||
}
|
||||
|
||||
STATIC mp_obj_t pyb_uart_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
pyb_uart_init_helper(args[0], n_args - 1, args + 1, kw_args);
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(pyb_uart_init_obj, 1, pyb_uart_init);
|
||||
|
||||
STATIC mp_obj_t pyb_uart_any(mp_obj_t self_in) {
|
||||
pyb_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
return MP_OBJ_NEW_SMALL_INT(uart_rx_any(self->uart_id));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_uart_any_obj, pyb_uart_any);
|
||||
|
||||
STATIC const mp_rom_map_elem_t pyb_uart_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&pyb_uart_init_obj) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&pyb_uart_any_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(pyb_uart_locals_dict, pyb_uart_locals_dict_table);
|
||||
|
||||
STATIC mp_uint_t pyb_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_t size, int *errcode) {
|
||||
pyb_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
|
||||
if (self->uart_id == 1) {
|
||||
mp_raise_msg(&mp_type_OSError, translate("UART(1) can't read"));
|
||||
}
|
||||
|
||||
// make sure we want at least 1 char
|
||||
if (size == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// wait for first char to become available
|
||||
if (!uart_rx_wait(self->timeout * 1000)) {
|
||||
*errcode = MP_EAGAIN;
|
||||
return MP_STREAM_ERROR;
|
||||
}
|
||||
|
||||
// read the data
|
||||
uint8_t *buf = buf_in;
|
||||
for (;;) {
|
||||
*buf++ = uart_rx_char();
|
||||
if (--size == 0 || !uart_rx_wait(self->timeout_char * 1000)) {
|
||||
// return number of bytes read
|
||||
return buf - (uint8_t*)buf_in;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STATIC mp_uint_t pyb_uart_write(mp_obj_t self_in, const void *buf_in, mp_uint_t size, int *errcode) {
|
||||
pyb_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
const byte *buf = buf_in;
|
||||
|
||||
/* TODO implement non-blocking
|
||||
// wait to be able to write the first character
|
||||
if (!uart_tx_wait(self, timeout)) {
|
||||
*errcode = EAGAIN;
|
||||
return MP_STREAM_ERROR;
|
||||
}
|
||||
*/
|
||||
|
||||
// write the data
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
uart_tx_one_char(self->uart_id, *buf++);
|
||||
}
|
||||
|
||||
// return number of bytes written
|
||||
return size;
|
||||
}
|
||||
|
||||
STATIC mp_uint_t pyb_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t arg, int *errcode) {
|
||||
pyb_uart_obj_t *self = self_in;
|
||||
mp_uint_t ret;
|
||||
if (request == MP_STREAM_POLL) {
|
||||
mp_uint_t flags = arg;
|
||||
ret = 0;
|
||||
if ((flags & MP_STREAM_POLL_RD) && uart_rx_any(self->uart_id)) {
|
||||
ret |= MP_STREAM_POLL_RD;
|
||||
}
|
||||
if ((flags & MP_STREAM_POLL_WR) && uart_tx_any_room(self->uart_id)) {
|
||||
ret |= MP_STREAM_POLL_WR;
|
||||
}
|
||||
} else {
|
||||
*errcode = MP_EINVAL;
|
||||
ret = MP_STREAM_ERROR;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
STATIC const mp_stream_p_t uart_stream_p = {
|
||||
.read = pyb_uart_read,
|
||||
.write = pyb_uart_write,
|
||||
.ioctl = pyb_uart_ioctl,
|
||||
.is_text = false,
|
||||
};
|
||||
|
||||
const mp_obj_type_t pyb_uart_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_UART,
|
||||
.print = pyb_uart_print,
|
||||
.make_new = pyb_uart_make_new,
|
||||
.getiter = mp_identity_getiter,
|
||||
.iternext = mp_stream_unbuffered_iter,
|
||||
.protocol = &uart_stream_p,
|
||||
.locals_dict = (mp_obj_dict_t*)&pyb_uart_locals_dict,
|
||||
};
|
@ -1,83 +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 <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/runtime.h"
|
||||
#include "user_interface.h"
|
||||
#include "etshal.h"
|
||||
|
||||
const mp_obj_type_t esp_wdt_type;
|
||||
|
||||
typedef struct _machine_wdt_obj_t {
|
||||
mp_obj_base_t base;
|
||||
} machine_wdt_obj_t;
|
||||
|
||||
STATIC machine_wdt_obj_t wdt_default = {{&esp_wdt_type}};
|
||||
|
||||
STATIC mp_obj_t machine_wdt_make_new(const mp_obj_type_t *type_in, size_t n_args, size_t n_kw, const mp_obj_t *args) {
|
||||
mp_arg_check_num(n_args, n_kw, 0, 1, false);
|
||||
|
||||
mp_int_t id = 0;
|
||||
if (n_args > 0) {
|
||||
id = mp_obj_get_int(args[0]);
|
||||
}
|
||||
|
||||
switch (id) {
|
||||
case 0:
|
||||
return &wdt_default;
|
||||
default:
|
||||
mp_raise_ValueError(NULL);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC mp_obj_t machine_wdt_feed(mp_obj_t self_in) {
|
||||
(void)self_in;
|
||||
system_soft_wdt_feed();
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_wdt_feed_obj, machine_wdt_feed);
|
||||
|
||||
STATIC mp_obj_t machine_wdt_deinit(mp_obj_t self_in) {
|
||||
(void)self_in;
|
||||
ets_wdt_disable();
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_wdt_deinit_obj, machine_wdt_deinit);
|
||||
|
||||
STATIC const mp_rom_map_elem_t machine_wdt_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_feed), MP_ROM_PTR(&machine_wdt_feed_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_wdt_deinit_obj) },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(machine_wdt_locals_dict, machine_wdt_locals_dict_table);
|
||||
|
||||
const mp_obj_type_t esp_wdt_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_WDT,
|
||||
.make_new = machine_wdt_make_new,
|
||||
.locals_dict = (mp_obj_dict_t*)&machine_wdt_locals_dict,
|
||||
};
|
@ -1,195 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014 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/compile.h"
|
||||
#include "py/frozenmod.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/stackctrl.h"
|
||||
#include "py/mperrno.h"
|
||||
#include "py/mphal.h"
|
||||
#include "py/gc.h"
|
||||
#include "lib/oofatfs/ff.h"
|
||||
#include "lib/mp-readline/readline.h"
|
||||
#include "lib/utils/pyexec.h"
|
||||
#include "gccollect.h"
|
||||
#include "user_interface.h"
|
||||
#include "common-hal/microcontroller/Pin.h"
|
||||
#include "common-hal/pulseio/PWMOut.h"
|
||||
|
||||
STATIC char heap[36 * 1024];
|
||||
|
||||
bool maybe_run(const char* filename, pyexec_result_t* exec_result) {
|
||||
mp_import_stat_t stat = mp_import_stat(filename);
|
||||
if (stat != MP_IMPORT_STAT_FILE) {
|
||||
return false;
|
||||
}
|
||||
mp_hal_stdout_tx_str(filename);
|
||||
mp_hal_stdout_tx_str(" output:\r\n");
|
||||
pyexec_file(filename, exec_result);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool serial_active = false;
|
||||
|
||||
STATIC bool start_mp(void) {
|
||||
pyexec_frozen_module("_boot.py");
|
||||
|
||||
pyexec_result_t result;
|
||||
bool found_boot = maybe_run("settings.txt", &result) ||
|
||||
maybe_run("settings.py", &result) ||
|
||||
maybe_run("boot.py", &result) ||
|
||||
maybe_run("boot.txt", &result);
|
||||
|
||||
if (!found_boot || !(result.return_code & PYEXEC_FORCED_EXIT)) {
|
||||
maybe_run("code.txt", &result) ||
|
||||
maybe_run("code.py", &result) ||
|
||||
maybe_run("main.py", &result) ||
|
||||
maybe_run("main.txt", &result);
|
||||
}
|
||||
|
||||
if (result.return_code & PYEXEC_FORCED_EXIT) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We can't detect connections so we wait for any character to mark the serial active.
|
||||
if (!serial_active) {
|
||||
mp_hal_stdin_rx_chr();
|
||||
serial_active = true;
|
||||
}
|
||||
mp_hal_stdout_tx_str("\r\n\r\n");
|
||||
mp_hal_stdout_tx_str("Press any key to enter the REPL. Use CTRL-D to soft reset.\r\n");
|
||||
return mp_hal_stdin_rx_chr() == CHAR_CTRL_D;
|
||||
}
|
||||
|
||||
STATIC void mp_reset(void) {
|
||||
mp_stack_set_top((void*)0x40000000);
|
||||
mp_stack_set_limit(8192);
|
||||
mp_hal_init();
|
||||
gc_init(heap, heap + sizeof(heap));
|
||||
mp_init();
|
||||
mp_obj_list_init(mp_sys_path, 0);
|
||||
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR_)); // current dir (or base dir of the script)
|
||||
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_));
|
||||
// Frozen modules are in their own pseudo-dir, e.g., ".frozen".
|
||||
// Prioritize .frozen over /lib.
|
||||
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_FROZEN_FAKE_DIR_QSTR));
|
||||
mp_obj_list_append(mp_sys_path, MP_OBJ_NEW_QSTR(MP_QSTR__slash_lib));
|
||||
|
||||
mp_obj_list_init(mp_sys_argv, 0);
|
||||
|
||||
reset_pins();
|
||||
#if MICROPY_EMIT_XTENSA || MICROPY_EMIT_INLINE_XTENSA
|
||||
extern void esp_native_code_init(void);
|
||||
esp_native_code_init();
|
||||
#endif
|
||||
pin_init0();
|
||||
readline_init0();
|
||||
dupterm_task_init();
|
||||
pwmout_reset();
|
||||
}
|
||||
|
||||
bool soft_reset(void) {
|
||||
gc_sweep_all();
|
||||
mp_hal_stdout_tx_str("PYB: soft reboot\r\n");
|
||||
mp_hal_delay_us(10000); // allow UART to flush output
|
||||
mp_reset();
|
||||
mp_hal_delay_us(1000); // Give the RTOS time to do housekeeping.
|
||||
return start_mp();
|
||||
}
|
||||
|
||||
void init_done(void) {
|
||||
mp_reset();
|
||||
mp_hal_delay_us(1000); // Give the RTOS time to do housekeeping.
|
||||
bool skip_repl = start_mp();
|
||||
mp_hal_stdout_tx_str("\r\n");
|
||||
|
||||
int exit_code = PYEXEC_FORCED_EXIT;
|
||||
while (true) {
|
||||
if (!skip_repl) {
|
||||
if (pyexec_mode_kind == PYEXEC_MODE_RAW_REPL) {
|
||||
exit_code = pyexec_raw_repl();
|
||||
} else {
|
||||
exit_code = pyexec_friendly_repl();
|
||||
}
|
||||
}
|
||||
if (exit_code == PYEXEC_FORCED_EXIT) {
|
||||
skip_repl = soft_reset();
|
||||
} else if (exit_code != 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void user_init(void) {
|
||||
system_init_done_cb(init_done);
|
||||
}
|
||||
|
||||
#if !MICROPY_VFS
|
||||
mp_lexer_t *mp_lexer_new_from_file(const char *filename) {
|
||||
mp_raise_OSError(MP_ENOENT);
|
||||
}
|
||||
|
||||
mp_import_stat_t mp_import_stat(const char *path) {
|
||||
(void)path;
|
||||
return MP_IMPORT_STAT_NO_EXIST;
|
||||
}
|
||||
|
||||
mp_obj_t mp_builtin_open(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) {
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_KW(mp_builtin_open_obj, 1, mp_builtin_open);
|
||||
|
||||
#endif
|
||||
|
||||
void MP_FASTCODE(nlr_jump_fail)(void *val) {
|
||||
printf("NLR jump failed\n");
|
||||
for (;;) {
|
||||
}
|
||||
}
|
||||
|
||||
//void __assert(const char *file, int line, const char *func, const char *expr) {
|
||||
void __assert(const char *file, int line, const char *expr) {
|
||||
printf("Assertion '%s' failed, at file %s:%d\n", expr, file, line);
|
||||
for (;;) {
|
||||
}
|
||||
}
|
||||
|
||||
#if !MICROPY_DEBUG_PRINTERS
|
||||
// With MICROPY_DEBUG_PRINTERS disabled DEBUG_printf is not defined but it
|
||||
// is still needed by esp-open-lwip for debugging output, so define it here.
|
||||
#include <stdarg.h>
|
||||
int mp_vprintf(const mp_print_t *print, const char *fmt, va_list args);
|
||||
int DEBUG_printf(const char *fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
int ret = mp_vprintf(&MICROPY_DEBUG_PRINTER_DEST, fmt, ap);
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
@ -1,41 +0,0 @@
|
||||
import sys
|
||||
import struct
|
||||
import hashlib
|
||||
|
||||
SEGS_MAX_SIZE = 0x9000
|
||||
|
||||
assert len(sys.argv) == 4
|
||||
|
||||
md5 = hashlib.md5()
|
||||
|
||||
with open(sys.argv[3], 'wb') as fout:
|
||||
|
||||
with open(sys.argv[1], 'rb') as f:
|
||||
data_flash = f.read()
|
||||
fout.write(data_flash)
|
||||
# First 4 bytes include flash size, etc. which may be changed
|
||||
# by esptool.py, etc.
|
||||
md5.update(data_flash[4:])
|
||||
print('flash ', len(data_flash))
|
||||
|
||||
with open(sys.argv[2], 'rb') as f:
|
||||
data_rom = f.read()
|
||||
|
||||
print(SEGS_MAX_SIZE, len(data_flash))
|
||||
pad = b'\xff' * (SEGS_MAX_SIZE - len(data_flash))
|
||||
assert len(pad) >= 4
|
||||
fout.write(pad[:-4])
|
||||
md5.update(pad[:-4])
|
||||
len_data = struct.pack("I", SEGS_MAX_SIZE + len(data_rom))
|
||||
fout.write(len_data)
|
||||
md5.update(len_data)
|
||||
print('padding ', len(pad))
|
||||
|
||||
fout.write(data_rom)
|
||||
md5.update(data_rom)
|
||||
print('irom0text', len(data_rom))
|
||||
|
||||
fout.write(md5.digest())
|
||||
|
||||
print('total ', SEGS_MAX_SIZE + len(data_rom))
|
||||
print('md5 ', md5.hexdigest())
|
@ -1,361 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015 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 <stdio.h>
|
||||
|
||||
#include "py/gc.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/mperrno.h"
|
||||
#include "py/mphal.h"
|
||||
#include "supervisor/shared/translate.h"
|
||||
#include "uart.h"
|
||||
#include "user_interface.h"
|
||||
#include "mem.h"
|
||||
#include "modmachine.h"
|
||||
|
||||
#define MODESP_INCLUDE_CONSTANTS (1)
|
||||
|
||||
void error_check(bool status, const compressed_string_t *msg) {
|
||||
if (!status) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, msg));
|
||||
}
|
||||
}
|
||||
|
||||
STATIC mp_obj_t esp_osdebug(mp_obj_t val) {
|
||||
if (val == mp_const_none) {
|
||||
uart_os_config(-1);
|
||||
} else {
|
||||
uart_os_config(mp_obj_get_int(val));
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp_osdebug_obj, esp_osdebug);
|
||||
|
||||
STATIC mp_obj_t esp_sleep_type(size_t n_args, const mp_obj_t *args) {
|
||||
if (n_args == 0) {
|
||||
return mp_obj_new_int(wifi_get_sleep_type());
|
||||
} else {
|
||||
wifi_set_sleep_type(mp_obj_get_int(args[0]));
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp_sleep_type_obj, 0, 1, esp_sleep_type);
|
||||
|
||||
STATIC mp_obj_t esp_deepsleep(size_t n_args, const mp_obj_t *args) {
|
||||
uint32_t sleep_us = n_args > 0 ? mp_obj_get_int(args[0]) : 0;
|
||||
// prepare for RTC reset at wake up
|
||||
rtc_prepare_deepsleep(sleep_us);
|
||||
system_deep_sleep_set_option(n_args > 1 ? mp_obj_get_int(args[1]) : 0);
|
||||
system_deep_sleep(sleep_us);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp_deepsleep_obj, 0, 2, esp_deepsleep);
|
||||
|
||||
STATIC mp_obj_t esp_flash_id() {
|
||||
return mp_obj_new_int(spi_flash_get_id());
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(esp_flash_id_obj, esp_flash_id);
|
||||
|
||||
STATIC mp_obj_t esp_flash_read(mp_obj_t offset_in, mp_obj_t len_or_buf_in) {
|
||||
mp_int_t offset = mp_obj_get_int(offset_in);
|
||||
|
||||
mp_int_t len;
|
||||
byte *buf;
|
||||
bool alloc_buf = MP_OBJ_IS_INT(len_or_buf_in);
|
||||
|
||||
if (alloc_buf) {
|
||||
len = mp_obj_get_int(len_or_buf_in);
|
||||
buf = m_new(byte, len);
|
||||
} else {
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(len_or_buf_in, &bufinfo, MP_BUFFER_WRITE);
|
||||
len = bufinfo.len;
|
||||
buf = bufinfo.buf;
|
||||
}
|
||||
|
||||
// We know that allocation will be 4-byte aligned for sure
|
||||
SpiFlashOpResult res = spi_flash_read(offset, (uint32_t*)buf, len);
|
||||
if (res == SPI_FLASH_RESULT_OK) {
|
||||
if (alloc_buf) {
|
||||
return mp_obj_new_bytes(buf, len);
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
if (alloc_buf) {
|
||||
m_del(byte, buf, len);
|
||||
}
|
||||
mp_raise_OSError(res == SPI_FLASH_RESULT_TIMEOUT ? MP_ETIMEDOUT : MP_EIO);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp_flash_read_obj, esp_flash_read);
|
||||
|
||||
STATIC mp_obj_t esp_flash_write(mp_obj_t offset_in, const mp_obj_t buf_in) {
|
||||
mp_int_t offset = mp_obj_get_int(offset_in);
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(buf_in, &bufinfo, MP_BUFFER_READ);
|
||||
if (bufinfo.len & 0x3) {
|
||||
mp_raise_ValueError(translate("len must be multiple of 4"));
|
||||
}
|
||||
SpiFlashOpResult res = spi_flash_write(offset, bufinfo.buf, bufinfo.len);
|
||||
if (res == SPI_FLASH_RESULT_OK) {
|
||||
return mp_const_none;
|
||||
}
|
||||
mp_raise_OSError(res == SPI_FLASH_RESULT_TIMEOUT ? MP_ETIMEDOUT : MP_EIO);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp_flash_write_obj, esp_flash_write);
|
||||
|
||||
STATIC mp_obj_t esp_flash_erase(mp_obj_t sector_in) {
|
||||
mp_int_t sector = mp_obj_get_int(sector_in);
|
||||
SpiFlashOpResult res = spi_flash_erase_sector(sector);
|
||||
if (res == SPI_FLASH_RESULT_OK) {
|
||||
return mp_const_none;
|
||||
}
|
||||
mp_raise_OSError(res == SPI_FLASH_RESULT_TIMEOUT ? MP_ETIMEDOUT : MP_EIO);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp_flash_erase_obj, esp_flash_erase);
|
||||
|
||||
STATIC mp_obj_t esp_flash_size(void) {
|
||||
extern char flashchip;
|
||||
// For SDK 1.5.2, either address has shifted and not mirrored in
|
||||
// eagle.rom.addr.v6.ld, or extra initial member was added.
|
||||
SpiFlashChip *flash = (SpiFlashChip*)(&flashchip + 4);
|
||||
#if 0
|
||||
printf("deviceId: %x\n", flash->deviceId);
|
||||
printf("chip_size: %u\n", flash->chip_size);
|
||||
printf("block_size: %u\n", flash->block_size);
|
||||
printf("sector_size: %u\n", flash->sector_size);
|
||||
printf("page_size: %u\n", flash->page_size);
|
||||
printf("status_mask: %u\n", flash->status_mask);
|
||||
#endif
|
||||
return mp_obj_new_int_from_uint(flash->chip_size);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(esp_flash_size_obj, esp_flash_size);
|
||||
|
||||
// If there's just 1 loadable segment at the start of flash,
|
||||
// we assume there's a yaota8266 bootloader.
|
||||
#define IS_OTA_FIRMWARE() ((*(uint32_t*)0x40200000 & 0xff00) == 0x100)
|
||||
|
||||
extern byte _firmware_size[];
|
||||
|
||||
STATIC mp_obj_t esp_flash_user_start(void) {
|
||||
return MP_OBJ_NEW_SMALL_INT((uint32_t)_firmware_size);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(esp_flash_user_start_obj, esp_flash_user_start);
|
||||
|
||||
STATIC mp_obj_t esp_check_fw(void) {
|
||||
MD5_CTX ctx;
|
||||
char *fw_start = (char*)0x40200000;
|
||||
if (IS_OTA_FIRMWARE()) {
|
||||
// Skip yaota8266 bootloader
|
||||
fw_start += 0x3c000;
|
||||
}
|
||||
|
||||
uint32_t size = *(uint32_t*)(fw_start + 0x8ffc);
|
||||
printf("size: %d\n", size);
|
||||
if (size > 1024 * 1024) {
|
||||
printf("Invalid size\n");
|
||||
return mp_const_false;
|
||||
}
|
||||
MD5Init(&ctx);
|
||||
MD5Update(&ctx, fw_start + 4, size - 4);
|
||||
unsigned char digest[16];
|
||||
MD5Final(digest, &ctx);
|
||||
printf("md5: ");
|
||||
for (int i = 0; i < 16; i++) {
|
||||
printf("%02x", digest[i]);
|
||||
}
|
||||
printf("\n");
|
||||
return mp_obj_new_bool(memcmp(digest, fw_start + size, sizeof(digest)) == 0);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(esp_check_fw_obj, esp_check_fw);
|
||||
|
||||
STATIC mp_obj_t esp_freemem() {
|
||||
return MP_OBJ_NEW_SMALL_INT(system_get_free_heap_size());
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(esp_freemem_obj, esp_freemem);
|
||||
|
||||
STATIC mp_obj_t esp_meminfo() {
|
||||
system_print_meminfo();
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(esp_meminfo_obj, esp_meminfo);
|
||||
|
||||
STATIC mp_obj_t esp_malloc(mp_obj_t size_in) {
|
||||
return MP_OBJ_NEW_SMALL_INT((mp_uint_t)os_malloc(mp_obj_get_int(size_in)));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp_malloc_obj, esp_malloc);
|
||||
|
||||
STATIC mp_obj_t esp_free(mp_obj_t addr_in) {
|
||||
os_free((void*)mp_obj_get_int(addr_in));
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp_free_obj, esp_free);
|
||||
|
||||
STATIC mp_obj_t esp_esf_free_bufs(mp_obj_t idx_in) {
|
||||
return MP_OBJ_NEW_SMALL_INT(ets_esf_free_bufs(mp_obj_get_int(idx_in)));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp_esf_free_bufs_obj, esp_esf_free_bufs);
|
||||
|
||||
#if MICROPY_EMIT_XTENSA || MICROPY_EMIT_INLINE_XTENSA
|
||||
|
||||
// We provide here a way of committing executable data to a region from
|
||||
// which it can be executed by the CPU. There are 2 such writable regions:
|
||||
// - iram1, which may have some space left at the end of it
|
||||
// - memory-mapped flash rom
|
||||
//
|
||||
// By default the iram1 region (the space at the end of it) is used. The
|
||||
// user can select iram1 or a section of flash by calling the
|
||||
// esp.set_native_code_location() function; see below. If flash is selected
|
||||
// then it is erased as needed.
|
||||
|
||||
#include "gccollect.h"
|
||||
|
||||
#define IRAM1_END (0x40108000)
|
||||
#define FLASH_START (0x40200000)
|
||||
#define FLASH_END (0x40300000)
|
||||
#define FLASH_SEC_SIZE (4096)
|
||||
|
||||
#define ESP_NATIVE_CODE_IRAM1 (0)
|
||||
#define ESP_NATIVE_CODE_FLASH (1)
|
||||
|
||||
extern uint32_t _lit4_end;
|
||||
STATIC uint32_t esp_native_code_location;
|
||||
STATIC uint32_t esp_native_code_start;
|
||||
STATIC uint32_t esp_native_code_end;
|
||||
STATIC uint32_t esp_native_code_cur;
|
||||
STATIC uint32_t esp_native_code_erased;
|
||||
|
||||
void esp_native_code_init(void) {
|
||||
esp_native_code_location = ESP_NATIVE_CODE_IRAM1;
|
||||
esp_native_code_start = (uint32_t)&_lit4_end;
|
||||
esp_native_code_end = IRAM1_END;
|
||||
esp_native_code_cur = esp_native_code_start;
|
||||
esp_native_code_erased = 0;
|
||||
}
|
||||
|
||||
void esp_native_code_gc_collect(void) {
|
||||
void *src;
|
||||
if (esp_native_code_location == ESP_NATIVE_CODE_IRAM1) {
|
||||
src = (void*)esp_native_code_start;
|
||||
} else {
|
||||
src = (void*)(FLASH_START + esp_native_code_start);
|
||||
}
|
||||
gc_collect_root(src, (esp_native_code_end - esp_native_code_start) / sizeof(uint32_t));
|
||||
}
|
||||
|
||||
void *esp_native_code_commit(void *buf, size_t len) {
|
||||
//printf("COMMIT(buf=%p, len=%u, start=%08x, cur=%08x, end=%08x, erased=%08x)\n", buf, len, esp_native_code_start, esp_native_code_cur, esp_native_code_end, esp_native_code_erased);
|
||||
|
||||
len = (len + 3) & ~3;
|
||||
if (esp_native_code_cur + len > esp_native_code_end) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_MemoryError,
|
||||
translate("memory allocation failed, allocating %u bytes for native code"), (uint)len));
|
||||
}
|
||||
|
||||
void *dest;
|
||||
if (esp_native_code_location == ESP_NATIVE_CODE_IRAM1) {
|
||||
dest = (void*)esp_native_code_cur;
|
||||
memcpy(dest, buf, len);
|
||||
} else {
|
||||
SpiFlashOpResult res;
|
||||
while (esp_native_code_erased < esp_native_code_cur + len) {
|
||||
res = spi_flash_erase_sector(esp_native_code_erased / FLASH_SEC_SIZE);
|
||||
if (res != SPI_FLASH_RESULT_OK) {
|
||||
break;
|
||||
}
|
||||
esp_native_code_erased += FLASH_SEC_SIZE;
|
||||
}
|
||||
if (res == SPI_FLASH_RESULT_OK) {
|
||||
res = spi_flash_write(esp_native_code_cur, buf, len);
|
||||
}
|
||||
if (res != SPI_FLASH_RESULT_OK) {
|
||||
mp_raise_OSError(res == SPI_FLASH_RESULT_TIMEOUT ? MP_ETIMEDOUT : MP_EIO);
|
||||
}
|
||||
dest = (void*)(FLASH_START + esp_native_code_cur);
|
||||
}
|
||||
|
||||
esp_native_code_cur += len;
|
||||
|
||||
return dest;
|
||||
}
|
||||
|
||||
STATIC mp_obj_t esp_set_native_code_location(mp_obj_t start_in, mp_obj_t len_in) {
|
||||
if (start_in == mp_const_none && len_in == mp_const_none) {
|
||||
// use end of iram1 region
|
||||
esp_native_code_init();
|
||||
} else {
|
||||
// use flash; input params are byte offsets from start of flash
|
||||
esp_native_code_location = ESP_NATIVE_CODE_FLASH;
|
||||
esp_native_code_start = mp_obj_get_int(start_in);
|
||||
esp_native_code_end = esp_native_code_start + mp_obj_get_int(len_in);
|
||||
esp_native_code_cur = esp_native_code_start;
|
||||
esp_native_code_erased = esp_native_code_start;
|
||||
// memory-mapped flash is limited in extents to 1MByte
|
||||
if (esp_native_code_end > FLASH_END - FLASH_START) {
|
||||
mp_raise_ValueError(translate("flash location must be below 1MByte"));
|
||||
}
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_2(esp_set_native_code_location_obj, esp_set_native_code_location);
|
||||
|
||||
#endif
|
||||
|
||||
STATIC const mp_rom_map_elem_t esp_module_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_esp) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_osdebug), MP_ROM_PTR(&esp_osdebug_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_sleep_type), MP_ROM_PTR(&esp_sleep_type_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_deepsleep), MP_ROM_PTR(&esp_deepsleep_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_flash_id), MP_ROM_PTR(&esp_flash_id_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_flash_read), MP_ROM_PTR(&esp_flash_read_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_flash_write), MP_ROM_PTR(&esp_flash_write_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_flash_erase), MP_ROM_PTR(&esp_flash_erase_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_flash_size), MP_ROM_PTR(&esp_flash_size_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_flash_user_start), MP_ROM_PTR(&esp_flash_user_start_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_freemem), MP_ROM_PTR(&esp_freemem_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_meminfo), MP_ROM_PTR(&esp_meminfo_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_check_fw), MP_ROM_PTR(&esp_check_fw_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_info), MP_ROM_PTR(&pyb_info_obj) }, // TODO delete/rename/move elsewhere
|
||||
{ MP_ROM_QSTR(MP_QSTR_malloc), MP_ROM_PTR(&esp_malloc_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_free), MP_ROM_PTR(&esp_free_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_esf_free_bufs), MP_ROM_PTR(&esp_esf_free_bufs_obj) },
|
||||
#if MICROPY_EMIT_XTENSA || MICROPY_EMIT_INLINE_XTENSA
|
||||
{ MP_ROM_QSTR(MP_QSTR_set_native_code_location), MP_ROM_PTR(&esp_set_native_code_location_obj) },
|
||||
#endif
|
||||
|
||||
#if MODESP_INCLUDE_CONSTANTS
|
||||
{ MP_ROM_QSTR(MP_QSTR_SLEEP_NONE), MP_ROM_INT(NONE_SLEEP_T) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_SLEEP_LIGHT), MP_ROM_INT(LIGHT_SLEEP_T) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_SLEEP_MODEM), MP_ROM_INT(MODEM_SLEEP_T) },
|
||||
#endif
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(esp_module_globals, esp_module_globals_table);
|
||||
|
||||
const mp_obj_module_t esp_module = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t*)&esp_module_globals,
|
||||
};
|
@ -1,284 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013-2015 Damien P. George
|
||||
* 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 <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "py/obj.h"
|
||||
#include "py/runtime.h"
|
||||
#include "extmod/machine_mem.h"
|
||||
#include "extmod/machine_signal.h"
|
||||
#include "extmod/machine_pulse.h"
|
||||
#include "extmod/machine_i2c.h"
|
||||
#include "modmachine.h"
|
||||
#include "supervisor/shared/translate.h"
|
||||
|
||||
#include "xtirq.h"
|
||||
#include "os_type.h"
|
||||
#include "osapi.h"
|
||||
#include "etshal.h"
|
||||
#include "ets_alt_task.h"
|
||||
#include "user_interface.h"
|
||||
|
||||
#if MICROPY_PY_MACHINE
|
||||
|
||||
//#define MACHINE_WAKE_IDLE (0x01)
|
||||
//#define MACHINE_WAKE_SLEEP (0x02)
|
||||
#define MACHINE_WAKE_DEEPSLEEP (0x04)
|
||||
|
||||
extern const mp_obj_type_t esp_wdt_type;
|
||||
|
||||
STATIC mp_obj_t machine_freq(size_t n_args, const mp_obj_t *args) {
|
||||
if (n_args == 0) {
|
||||
// get
|
||||
return mp_obj_new_int(system_get_cpu_freq() * 1000000);
|
||||
} else {
|
||||
// set
|
||||
mp_int_t freq = mp_obj_get_int(args[0]) / 1000000;
|
||||
if (freq != 80 && freq != 160) {
|
||||
mp_raise_ValueError(translate("frequency can only be either 80Mhz or 160MHz"));
|
||||
}
|
||||
system_update_cpu_freq(freq);
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(machine_freq_obj, 0, 1, machine_freq);
|
||||
|
||||
STATIC mp_obj_t machine_reset(void) {
|
||||
system_restart();
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_reset_obj, machine_reset);
|
||||
|
||||
STATIC mp_obj_t machine_reset_cause(void) {
|
||||
return MP_OBJ_NEW_SMALL_INT(system_get_rst_info()->reason);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_reset_cause_obj, machine_reset_cause);
|
||||
|
||||
STATIC mp_obj_t machine_unique_id(void) {
|
||||
uint32_t id = system_get_chip_id();
|
||||
return mp_obj_new_bytes((byte*)&id, sizeof(id));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_unique_id_obj, machine_unique_id);
|
||||
|
||||
STATIC mp_obj_t machine_idle(void) {
|
||||
uint32_t t = mp_hal_ticks_cpu();
|
||||
asm("waiti 0");
|
||||
t = mp_hal_ticks_cpu() - t;
|
||||
return MP_OBJ_NEW_SMALL_INT(t);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_idle_obj, machine_idle);
|
||||
|
||||
STATIC mp_obj_t machine_sleep(void) {
|
||||
printf("Warning: not yet implemented\n");
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_sleep_obj, machine_sleep);
|
||||
|
||||
STATIC mp_obj_t machine_deepsleep(void) {
|
||||
// default to sleep forever
|
||||
uint32_t sleep_us = 0;
|
||||
|
||||
// see if RTC.ALARM0 should wake the device
|
||||
if (pyb_rtc_alarm0_wake & MACHINE_WAKE_DEEPSLEEP) {
|
||||
uint64_t t = pyb_rtc_get_us_since_2000();
|
||||
if (pyb_rtc_alarm0_expiry <= t) {
|
||||
sleep_us = 1; // alarm already expired so wake immediately
|
||||
} else {
|
||||
uint64_t delta = pyb_rtc_alarm0_expiry - t;
|
||||
if (delta <= 0xffffffff) {
|
||||
// sleep for the desired time
|
||||
sleep_us = delta;
|
||||
} else {
|
||||
// overflow, just set to maximum sleep time
|
||||
sleep_us = 0xffffffff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// prepare for RTC reset at wake up
|
||||
rtc_prepare_deepsleep(sleep_us);
|
||||
// put the device in a deep-sleep state
|
||||
system_deep_sleep_set_option(0); // default power down mode; TODO check this
|
||||
system_deep_sleep(sleep_us);
|
||||
|
||||
for (;;) {
|
||||
// we must not return
|
||||
ets_loop_iter();
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_0(machine_deepsleep_obj, machine_deepsleep);
|
||||
|
||||
typedef struct _esp_timer_obj_t {
|
||||
mp_obj_base_t base;
|
||||
os_timer_t timer;
|
||||
mp_obj_t callback;
|
||||
} esp_timer_obj_t;
|
||||
|
||||
const mp_obj_type_t esp_timer_type;
|
||||
|
||||
STATIC void esp_timer_print(const mp_print_t *print, mp_obj_t self_in, mp_print_kind_t kind) {
|
||||
esp_timer_obj_t *self = self_in;
|
||||
mp_printf(print, "Timer(%p)", &self->timer);
|
||||
}
|
||||
|
||||
STATIC mp_obj_t esp_timer_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, 1, false);
|
||||
esp_timer_obj_t *tim = m_new_obj(esp_timer_obj_t);
|
||||
tim->base.type = &esp_timer_type;
|
||||
return tim;
|
||||
}
|
||||
|
||||
STATIC void esp_timer_cb(void *arg) {
|
||||
esp_timer_obj_t *self = arg;
|
||||
mp_sched_schedule(self->callback, self);
|
||||
}
|
||||
|
||||
STATIC mp_obj_t esp_timer_init_helper(esp_timer_obj_t *self, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
// { MP_QSTR_freq, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
|
||||
{ MP_QSTR_period, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0xffffffff} },
|
||||
{ MP_QSTR_mode, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} },
|
||||
{ MP_QSTR_callback, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
|
||||
};
|
||||
|
||||
// parse args
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
self->callback = args[2].u_obj;
|
||||
// Be sure to disarm timer before making any changes
|
||||
os_timer_disarm(&self->timer);
|
||||
os_timer_setfn(&self->timer, esp_timer_cb, self);
|
||||
os_timer_arm(&self->timer, args[0].u_int, args[1].u_int);
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
STATIC mp_obj_t esp_timer_init(size_t n_args, const mp_obj_t *args, mp_map_t *kw_args) {
|
||||
return esp_timer_init_helper(args[0], n_args - 1, args + 1, kw_args);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(esp_timer_init_obj, 1, esp_timer_init);
|
||||
|
||||
STATIC mp_obj_t esp_timer_deinit(mp_obj_t self_in) {
|
||||
esp_timer_obj_t *self = self_in;
|
||||
os_timer_disarm(&self->timer);
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp_timer_deinit_obj, esp_timer_deinit);
|
||||
|
||||
STATIC const mp_rom_map_elem_t esp_timer_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&esp_timer_deinit_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&esp_timer_init_obj) },
|
||||
// { MP_ROM_QSTR(MP_QSTR_callback), MP_ROM_PTR(&esp_timer_callback_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_ONE_SHOT), MP_ROM_INT(false) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_PERIODIC), MP_ROM_INT(true) },
|
||||
};
|
||||
STATIC MP_DEFINE_CONST_DICT(esp_timer_locals_dict, esp_timer_locals_dict_table);
|
||||
|
||||
const mp_obj_type_t esp_timer_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_Timer,
|
||||
.print = esp_timer_print,
|
||||
.make_new = esp_timer_make_new,
|
||||
.locals_dict = (mp_obj_dict_t*)&esp_timer_locals_dict,
|
||||
};
|
||||
|
||||
// this bit is unused in the Xtensa PS register
|
||||
#define ETS_LOOP_ITER_BIT (12)
|
||||
|
||||
STATIC mp_obj_t machine_disable_irq(void) {
|
||||
uint32_t state = disable_irq();
|
||||
state = (state & ~(1 << ETS_LOOP_ITER_BIT)) | (ets_loop_iter_disable << ETS_LOOP_ITER_BIT);
|
||||
ets_loop_iter_disable = 1;
|
||||
return mp_obj_new_int(state);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(machine_disable_irq_obj, machine_disable_irq);
|
||||
|
||||
STATIC mp_obj_t machine_enable_irq(mp_obj_t state_in) {
|
||||
uint32_t state = mp_obj_get_int(state_in);
|
||||
ets_loop_iter_disable = (state >> ETS_LOOP_ITER_BIT) & 1;
|
||||
enable_irq(state & ~(1 << ETS_LOOP_ITER_BIT));
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(machine_enable_irq_obj, machine_enable_irq);
|
||||
|
||||
STATIC const mp_rom_map_elem_t machine_module_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_umachine) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_mem8), MP_ROM_PTR(&machine_mem8_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_mem16), MP_ROM_PTR(&machine_mem16_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_mem32), MP_ROM_PTR(&machine_mem32_obj) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_freq), MP_ROM_PTR(&machine_freq_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_reset), MP_ROM_PTR(&machine_reset_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_reset_cause), MP_ROM_PTR(&machine_reset_cause_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_unique_id), MP_ROM_PTR(&machine_unique_id_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_idle), MP_ROM_PTR(&machine_idle_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_sleep), MP_ROM_PTR(&machine_sleep_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_deepsleep), MP_ROM_PTR(&machine_deepsleep_obj) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_disable_irq), MP_ROM_PTR(&machine_disable_irq_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_enable_irq), MP_ROM_PTR(&machine_enable_irq_obj) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_time_pulse_us), MP_ROM_PTR(&machine_time_pulse_us_obj) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_RTC), MP_ROM_PTR(&pyb_rtc_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_Timer), MP_ROM_PTR(&esp_timer_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_WDT), MP_ROM_PTR(&esp_wdt_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_Pin), MP_ROM_PTR(&pyb_pin_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_Signal), MP_ROM_PTR(&machine_signal_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_PWM), MP_ROM_PTR(&pyb_pwm_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_ADC), MP_ROM_PTR(&pyb_adc_type) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&pyb_uart_type) },
|
||||
#if MICROPY_PY_MACHINE_I2C
|
||||
{ MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&machine_i2c_type) },
|
||||
#endif
|
||||
#if MICROPY_PY_MACHINE_SPI
|
||||
{ MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&machine_hspi_type) },
|
||||
#endif
|
||||
|
||||
// wake abilities
|
||||
{ MP_ROM_QSTR(MP_QSTR_DEEPSLEEP), MP_ROM_INT(MACHINE_WAKE_DEEPSLEEP) },
|
||||
|
||||
// reset causes
|
||||
{ MP_ROM_QSTR(MP_QSTR_PWRON_RESET), MP_ROM_INT(REASON_DEFAULT_RST) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_HARD_RESET), MP_ROM_INT(REASON_EXT_SYS_RST) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_DEEPSLEEP_RESET), MP_ROM_INT(REASON_DEEP_SLEEP_AWAKE) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_WDT_RESET), MP_ROM_INT(REASON_WDT_RST) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_SOFT_RESET), MP_ROM_INT(REASON_SOFT_RESTART) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(machine_module_globals, machine_module_globals_table);
|
||||
|
||||
const mp_obj_module_t mp_module_machine = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t*)&machine_module_globals,
|
||||
};
|
||||
|
||||
#endif // MICROPY_PY_MACHINE
|
@ -1,41 +0,0 @@
|
||||
#ifndef MICROPY_INCLUDED_ESP8266_MODMACHINE_H
|
||||
#define MICROPY_INCLUDED_ESP8266_MODMACHINE_H
|
||||
|
||||
#include "py/obj.h"
|
||||
|
||||
extern const mp_obj_type_t pyb_pin_type;
|
||||
extern const mp_obj_type_t pyb_pwm_type;
|
||||
extern const mp_obj_type_t pyb_adc_type;
|
||||
extern const mp_obj_type_t pyb_rtc_type;
|
||||
extern const mp_obj_type_t pyb_uart_type;
|
||||
extern const mp_obj_type_t pyb_i2c_type;
|
||||
extern const mp_obj_type_t machine_hspi_type;
|
||||
|
||||
MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_info_obj);
|
||||
|
||||
typedef struct _pyb_pin_obj_t {
|
||||
mp_obj_base_t base;
|
||||
uint16_t phys_port;
|
||||
uint16_t func;
|
||||
uint32_t periph;
|
||||
} pyb_pin_obj_t;
|
||||
|
||||
const pyb_pin_obj_t pyb_pin_obj[16 + 1];
|
||||
|
||||
void pin_init0(void);
|
||||
void pin_intr_handler_iram(void *arg);
|
||||
void pin_intr_handler(uint32_t);
|
||||
|
||||
uint mp_obj_get_pin(mp_obj_t pin_in);
|
||||
pyb_pin_obj_t *mp_obj_get_pin_obj(mp_obj_t pin_in);
|
||||
int pin_get(uint pin);
|
||||
void pin_set(uint pin, int value);
|
||||
|
||||
extern uint32_t pyb_rtc_alarm0_wake;
|
||||
extern uint64_t pyb_rtc_alarm0_expiry;
|
||||
|
||||
void pyb_rtc_set_us_since_2000(uint64_t nowus);
|
||||
uint64_t pyb_rtc_get_us_since_2000();
|
||||
void rtc_prepare_deepsleep(uint64_t sleep_us);
|
||||
|
||||
#endif // MICROPY_INCLUDED_ESP8266_MODMACHINE_H
|
@ -1,535 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2015-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 <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "py/objlist.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/mphal.h"
|
||||
#include "lib/netutils/netutils.h"
|
||||
#include "supervisor/shared/translate.h"
|
||||
#include "queue.h"
|
||||
#include "user_interface.h"
|
||||
#include "espconn.h"
|
||||
#include "spi_flash.h"
|
||||
#include "ets_alt_task.h"
|
||||
#include "lwip/dns.h"
|
||||
|
||||
#define MODNETWORK_INCLUDE_CONSTANTS (1)
|
||||
|
||||
typedef struct _wlan_if_obj_t {
|
||||
mp_obj_base_t base;
|
||||
int if_id;
|
||||
} wlan_if_obj_t;
|
||||
|
||||
void error_check(bool status, const compressed_string_t *msg);
|
||||
const mp_obj_type_t wlan_if_type;
|
||||
|
||||
STATIC const wlan_if_obj_t wlan_objs[] = {
|
||||
{{&wlan_if_type}, STATION_IF},
|
||||
{{&wlan_if_type}, SOFTAP_IF},
|
||||
};
|
||||
|
||||
STATIC void require_if(mp_obj_t wlan_if, int if_no) {
|
||||
wlan_if_obj_t *self = MP_OBJ_TO_PTR(wlan_if);
|
||||
if (self->if_id != if_no) {
|
||||
error_check(false, if_no == STATION_IF ? translate("STA required") : translate("AP required"));
|
||||
}
|
||||
}
|
||||
|
||||
STATIC mp_obj_t get_wlan(size_t n_args, const mp_obj_t *args) {
|
||||
int idx = 0;
|
||||
if (n_args > 0) {
|
||||
idx = mp_obj_get_int(args[0]);
|
||||
if (idx < 0 || idx >= sizeof(wlan_objs)) {
|
||||
mp_raise_ValueError(NULL);
|
||||
}
|
||||
}
|
||||
return MP_OBJ_FROM_PTR(&wlan_objs[idx]);
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(get_wlan_obj, 0, 1, get_wlan);
|
||||
|
||||
STATIC mp_obj_t esp_active(size_t n_args, const mp_obj_t *args) {
|
||||
wlan_if_obj_t *self = MP_OBJ_TO_PTR(args[0]);
|
||||
uint32_t mode = wifi_get_opmode();
|
||||
if (n_args > 1) {
|
||||
int mask = self->if_id == STATION_IF ? STATION_MODE : SOFTAP_MODE;
|
||||
if (mp_obj_get_int(args[1]) != 0) {
|
||||
mode |= mask;
|
||||
} else {
|
||||
mode &= ~mask;
|
||||
}
|
||||
error_check(wifi_set_opmode(mode), translate("Cannot update i/f status"));
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
// Get active status
|
||||
if (self->if_id == STATION_IF) {
|
||||
return mp_obj_new_bool(mode & STATION_MODE);
|
||||
} else {
|
||||
return mp_obj_new_bool(mode & SOFTAP_MODE);
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp_active_obj, 1, 2, esp_active);
|
||||
|
||||
STATIC mp_obj_t esp_connect(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
|
||||
enum { ARG_ssid, ARG_password, ARG_bssid };
|
||||
static const mp_arg_t allowed_args[] = {
|
||||
{ MP_QSTR_, MP_ARG_OBJ, {.u_obj = mp_const_none} },
|
||||
{ MP_QSTR_, MP_ARG_OBJ, {.u_obj = mp_const_none} },
|
||||
{ MP_QSTR_bssid, MP_ARG_KW_ONLY | MP_ARG_OBJ, {.u_obj = mp_const_none} },
|
||||
};
|
||||
|
||||
// parse args
|
||||
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
|
||||
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
|
||||
|
||||
require_if(pos_args[0], STATION_IF);
|
||||
struct station_config config = {{0}};
|
||||
size_t len;
|
||||
const char *p;
|
||||
bool set_config = false;
|
||||
|
||||
// set parameters based on given args
|
||||
if (args[ARG_ssid].u_obj != mp_const_none) {
|
||||
p = mp_obj_str_get_data(args[ARG_ssid].u_obj, &len);
|
||||
len = MIN(len, sizeof(config.ssid));
|
||||
memcpy(config.ssid, p, len);
|
||||
set_config = true;
|
||||
}
|
||||
if (args[ARG_password].u_obj != mp_const_none) {
|
||||
p = mp_obj_str_get_data(args[ARG_password].u_obj, &len);
|
||||
len = MIN(len, sizeof(config.password));
|
||||
memcpy(config.password, p, len);
|
||||
set_config = true;
|
||||
}
|
||||
if (args[ARG_bssid].u_obj != mp_const_none) {
|
||||
p = mp_obj_str_get_data(args[ARG_bssid].u_obj, &len);
|
||||
if (len != sizeof(config.bssid)) {
|
||||
mp_raise_ValueError(NULL);
|
||||
}
|
||||
config.bssid_set = 1;
|
||||
memcpy(config.bssid, p, sizeof(config.bssid));
|
||||
set_config = true;
|
||||
}
|
||||
|
||||
if (set_config) {
|
||||
error_check(wifi_station_set_config(&config), translate("Cannot set STA config"));
|
||||
}
|
||||
error_check(wifi_station_connect(), translate("Cannot connect to AP"));
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(esp_connect_obj, 1, esp_connect);
|
||||
|
||||
STATIC mp_obj_t esp_disconnect(mp_obj_t self_in) {
|
||||
require_if(self_in, STATION_IF);
|
||||
error_check(wifi_station_disconnect(), translate("Cannot disconnect from AP"));
|
||||
return mp_const_none;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp_disconnect_obj, esp_disconnect);
|
||||
|
||||
STATIC mp_obj_t esp_status(size_t n_args, const mp_obj_t *args) {
|
||||
wlan_if_obj_t *self = MP_OBJ_TO_PTR(args[0]);
|
||||
if (n_args == 1) {
|
||||
// Get link status
|
||||
if (self->if_id == STATION_IF) {
|
||||
return MP_OBJ_NEW_SMALL_INT(wifi_station_get_connect_status());
|
||||
}
|
||||
return MP_OBJ_NEW_SMALL_INT(-1);
|
||||
} else {
|
||||
// Get specific status parameter
|
||||
switch (mp_obj_str_get_qstr(args[1])) {
|
||||
case MP_QSTR_rssi:
|
||||
if (self->if_id == STATION_IF) {
|
||||
return MP_OBJ_NEW_SMALL_INT(wifi_station_get_rssi());
|
||||
}
|
||||
}
|
||||
mp_raise_ValueError(translate("unknown status param"));
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp_status_obj, 1, 2, esp_status);
|
||||
|
||||
STATIC mp_obj_t *esp_scan_list = NULL;
|
||||
|
||||
STATIC void esp_scan_cb(void *result, STATUS status) {
|
||||
if (esp_scan_list == NULL) {
|
||||
// called unexpectedly
|
||||
return;
|
||||
}
|
||||
if (result && status == 0) {
|
||||
// we need to catch any memory errors
|
||||
nlr_buf_t nlr;
|
||||
if (nlr_push(&nlr) == 0) {
|
||||
for (struct bss_info *bs = result; bs; bs = STAILQ_NEXT(bs, next)) {
|
||||
mp_obj_tuple_t *t = mp_obj_new_tuple(6, NULL);
|
||||
#if 1
|
||||
// struct bss_info::ssid_len is not documented in SDK API Guide,
|
||||
// but is present in SDK headers since 1.4.0
|
||||
t->items[0] = mp_obj_new_bytes(bs->ssid, bs->ssid_len);
|
||||
#else
|
||||
t->items[0] = mp_obj_new_bytes(bs->ssid, strlen((char*)bs->ssid));
|
||||
#endif
|
||||
t->items[1] = mp_obj_new_bytes(bs->bssid, sizeof(bs->bssid));
|
||||
t->items[2] = MP_OBJ_NEW_SMALL_INT(bs->channel);
|
||||
t->items[3] = MP_OBJ_NEW_SMALL_INT(bs->rssi);
|
||||
t->items[4] = MP_OBJ_NEW_SMALL_INT(bs->authmode);
|
||||
t->items[5] = MP_OBJ_NEW_SMALL_INT(bs->is_hidden);
|
||||
mp_obj_list_append(*esp_scan_list, MP_OBJ_FROM_PTR(t));
|
||||
}
|
||||
nlr_pop();
|
||||
} else {
|
||||
mp_obj_print_exception(&mp_plat_print, MP_OBJ_FROM_PTR(nlr.ret_val));
|
||||
// indicate error
|
||||
*esp_scan_list = MP_OBJ_NULL;
|
||||
}
|
||||
} else {
|
||||
// indicate error
|
||||
*esp_scan_list = MP_OBJ_NULL;
|
||||
}
|
||||
esp_scan_list = NULL;
|
||||
}
|
||||
|
||||
STATIC mp_obj_t esp_scan(mp_obj_t self_in) {
|
||||
require_if(self_in, STATION_IF);
|
||||
if ((wifi_get_opmode() & STATION_MODE) == 0) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError,
|
||||
translate("STA must be active")));
|
||||
}
|
||||
mp_obj_t list = mp_obj_new_list(0, NULL);
|
||||
esp_scan_list = &list;
|
||||
wifi_station_scan(NULL, (scan_done_cb_t)esp_scan_cb);
|
||||
while (esp_scan_list != NULL) {
|
||||
// our esp_scan_cb is called via ets_loop_iter so it's safe to set the
|
||||
// esp_scan_list variable to NULL without disabling interrupts
|
||||
if (MP_STATE_VM(mp_pending_exception) != NULL) {
|
||||
esp_scan_list = NULL;
|
||||
mp_obj_t obj = MP_STATE_VM(mp_pending_exception);
|
||||
MP_STATE_VM(mp_pending_exception) = MP_OBJ_NULL;
|
||||
nlr_raise(obj);
|
||||
}
|
||||
ets_loop_iter();
|
||||
}
|
||||
if (list == MP_OBJ_NULL) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, translate("scan failed")));
|
||||
}
|
||||
return list;
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp_scan_obj, esp_scan);
|
||||
|
||||
/// \method isconnected()
|
||||
/// Return True if connected to an AP and an IP address has been assigned,
|
||||
/// false otherwise.
|
||||
STATIC mp_obj_t esp_isconnected(mp_obj_t self_in) {
|
||||
wlan_if_obj_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
if (self->if_id == STATION_IF) {
|
||||
if (wifi_station_get_connect_status() == STATION_GOT_IP) {
|
||||
return mp_const_true;
|
||||
}
|
||||
} else {
|
||||
if (wifi_softap_get_station_num() > 0) {
|
||||
return mp_const_true;
|
||||
}
|
||||
}
|
||||
return mp_const_false;
|
||||
}
|
||||
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_1(esp_isconnected_obj, esp_isconnected);
|
||||
|
||||
STATIC mp_obj_t esp_ifconfig(size_t n_args, const mp_obj_t *args) {
|
||||
wlan_if_obj_t *self = MP_OBJ_TO_PTR(args[0]);
|
||||
struct ip_info info;
|
||||
ip_addr_t dns_addr;
|
||||
wifi_get_ip_info(self->if_id, &info);
|
||||
if (n_args == 1) {
|
||||
// get
|
||||
dns_addr = dns_getserver(0);
|
||||
mp_obj_t tuple[4] = {
|
||||
netutils_format_ipv4_addr((uint8_t*)&info.ip, NETUTILS_BIG),
|
||||
netutils_format_ipv4_addr((uint8_t*)&info.netmask, NETUTILS_BIG),
|
||||
netutils_format_ipv4_addr((uint8_t*)&info.gw, NETUTILS_BIG),
|
||||
netutils_format_ipv4_addr((uint8_t*)&dns_addr, NETUTILS_BIG),
|
||||
};
|
||||
return mp_obj_new_tuple(4, tuple);
|
||||
} else {
|
||||
// set
|
||||
mp_obj_t *items;
|
||||
bool restart_dhcp_server = false;
|
||||
mp_obj_get_array_fixed_n(args[1], 4, &items);
|
||||
netutils_parse_ipv4_addr(items[0], (void*)&info.ip, NETUTILS_BIG);
|
||||
if (mp_obj_is_integer(items[1])) {
|
||||
// allow numeric netmask, i.e.:
|
||||
// 24 -> 255.255.255.0
|
||||
// 16 -> 255.255.0.0
|
||||
// etc...
|
||||
uint32_t* m = (uint32_t*)&info.netmask;
|
||||
*m = htonl(0xffffffff << (32 - mp_obj_get_int(items[1])));
|
||||
} else {
|
||||
netutils_parse_ipv4_addr(items[1], (void*)&info.netmask, NETUTILS_BIG);
|
||||
}
|
||||
netutils_parse_ipv4_addr(items[2], (void*)&info.gw, NETUTILS_BIG);
|
||||
netutils_parse_ipv4_addr(items[3], (void*)&dns_addr, NETUTILS_BIG);
|
||||
// To set a static IP we have to disable DHCP first
|
||||
if (self->if_id == STATION_IF) {
|
||||
wifi_station_dhcpc_stop();
|
||||
} else {
|
||||
restart_dhcp_server = wifi_softap_dhcps_status();
|
||||
wifi_softap_dhcps_stop();
|
||||
}
|
||||
if (!wifi_set_ip_info(self->if_id, &info)) {
|
||||
nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError,
|
||||
translate("wifi_set_ip_info() failed")));
|
||||
}
|
||||
dns_setserver(0, &dns_addr);
|
||||
if (restart_dhcp_server) {
|
||||
wifi_softap_dhcps_start();
|
||||
}
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp_ifconfig_obj, 1, 2, esp_ifconfig);
|
||||
|
||||
STATIC mp_obj_t esp_config(size_t n_args, const mp_obj_t *args, mp_map_t *kwargs) {
|
||||
if (n_args != 1 && kwargs->used != 0) {
|
||||
mp_raise_TypeError(translate("either pos or kw args are allowed"));
|
||||
}
|
||||
|
||||
wlan_if_obj_t *self = MP_OBJ_TO_PTR(args[0]);
|
||||
union {
|
||||
struct station_config sta;
|
||||
struct softap_config ap;
|
||||
} cfg;
|
||||
|
||||
if (self->if_id == STATION_IF) {
|
||||
error_check(wifi_station_get_config(&cfg.sta), translate("can't get STA config"));
|
||||
} else {
|
||||
error_check(wifi_softap_get_config(&cfg.ap), translate("can't get AP config"));
|
||||
}
|
||||
|
||||
int req_if = -1;
|
||||
|
||||
if (kwargs->used != 0) {
|
||||
|
||||
for (mp_uint_t i = 0; i < kwargs->alloc; i++) {
|
||||
if (MP_MAP_SLOT_IS_FILLED(kwargs, i)) {
|
||||
#define QS(x) (uintptr_t)MP_OBJ_NEW_QSTR(x)
|
||||
switch ((uintptr_t)kwargs->table[i].key) {
|
||||
case QS(MP_QSTR_mac): {
|
||||
mp_buffer_info_t bufinfo;
|
||||
mp_get_buffer_raise(kwargs->table[i].value, &bufinfo, MP_BUFFER_READ);
|
||||
if (bufinfo.len != 6) {
|
||||
mp_raise_ValueError(translate("invalid buffer length"));
|
||||
}
|
||||
wifi_set_macaddr(self->if_id, bufinfo.buf);
|
||||
break;
|
||||
}
|
||||
case QS(MP_QSTR_essid): {
|
||||
req_if = SOFTAP_IF;
|
||||
size_t len;
|
||||
const char *s = mp_obj_str_get_data(kwargs->table[i].value, &len);
|
||||
len = MIN(len, sizeof(cfg.ap.ssid));
|
||||
memcpy(cfg.ap.ssid, s, len);
|
||||
cfg.ap.ssid_len = len;
|
||||
break;
|
||||
}
|
||||
case QS(MP_QSTR_hidden): {
|
||||
req_if = SOFTAP_IF;
|
||||
cfg.ap.ssid_hidden = mp_obj_is_true(kwargs->table[i].value);
|
||||
break;
|
||||
}
|
||||
case QS(MP_QSTR_authmode): {
|
||||
req_if = SOFTAP_IF;
|
||||
cfg.ap.authmode = mp_obj_get_int(kwargs->table[i].value);
|
||||
break;
|
||||
}
|
||||
case QS(MP_QSTR_password): {
|
||||
req_if = SOFTAP_IF;
|
||||
size_t len;
|
||||
const char *s = mp_obj_str_get_data(kwargs->table[i].value, &len);
|
||||
len = MIN(len, sizeof(cfg.ap.password) - 1);
|
||||
memcpy(cfg.ap.password, s, len);
|
||||
cfg.ap.password[len] = 0;
|
||||
break;
|
||||
}
|
||||
case QS(MP_QSTR_channel): {
|
||||
req_if = SOFTAP_IF;
|
||||
cfg.ap.channel = mp_obj_get_int(kwargs->table[i].value);
|
||||
break;
|
||||
}
|
||||
case QS(MP_QSTR_dhcp_hostname): {
|
||||
req_if = STATION_IF;
|
||||
if (self->if_id == STATION_IF) {
|
||||
const char *s = mp_obj_str_get_str(kwargs->table[i].value);
|
||||
wifi_station_set_hostname((char*)s);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
goto unknown;
|
||||
}
|
||||
#undef QS
|
||||
}
|
||||
}
|
||||
|
||||
// We post-check interface requirements to save on code size
|
||||
if (req_if >= 0) {
|
||||
require_if(args[0], req_if);
|
||||
}
|
||||
|
||||
if (self->if_id == STATION_IF) {
|
||||
error_check(wifi_station_set_config(&cfg.sta), translate("can't set STA config"));
|
||||
} else {
|
||||
error_check(wifi_softap_set_config(&cfg.ap), translate("can't set AP config"));
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
|
||||
// Get config
|
||||
|
||||
if (n_args != 2) {
|
||||
mp_raise_TypeError(translate("can query only one param"));
|
||||
}
|
||||
|
||||
mp_obj_t val;
|
||||
|
||||
qstr key = mp_obj_str_get_qstr(args[1]);
|
||||
switch (key) {
|
||||
case MP_QSTR_mac: {
|
||||
uint8_t mac[6];
|
||||
wifi_get_macaddr(self->if_id, mac);
|
||||
return mp_obj_new_bytes(mac, sizeof(mac));
|
||||
}
|
||||
case MP_QSTR_essid:
|
||||
if (self->if_id == STATION_IF) {
|
||||
val = mp_obj_new_str((char*)cfg.sta.ssid, strlen((char*)cfg.sta.ssid));
|
||||
} else {
|
||||
val = mp_obj_new_str((char*)cfg.ap.ssid, cfg.ap.ssid_len);
|
||||
}
|
||||
break;
|
||||
case MP_QSTR_hidden:
|
||||
req_if = SOFTAP_IF;
|
||||
val = mp_obj_new_bool(cfg.ap.ssid_hidden);
|
||||
break;
|
||||
case MP_QSTR_authmode:
|
||||
req_if = SOFTAP_IF;
|
||||
val = MP_OBJ_NEW_SMALL_INT(cfg.ap.authmode);
|
||||
break;
|
||||
case MP_QSTR_channel:
|
||||
req_if = SOFTAP_IF;
|
||||
val = MP_OBJ_NEW_SMALL_INT(cfg.ap.channel);
|
||||
break;
|
||||
case MP_QSTR_dhcp_hostname: {
|
||||
req_if = STATION_IF;
|
||||
char* s = wifi_station_get_hostname();
|
||||
if (s == NULL) {
|
||||
val = MP_OBJ_NEW_QSTR(MP_QSTR_);
|
||||
} else {
|
||||
val = mp_obj_new_str(s, strlen(s));
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
goto unknown;
|
||||
}
|
||||
|
||||
// We post-check interface requirements to save on code size
|
||||
if (req_if >= 0) {
|
||||
require_if(args[0], req_if);
|
||||
}
|
||||
|
||||
return val;
|
||||
|
||||
unknown:
|
||||
mp_raise_ValueError(translate("unknown config param"));
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(esp_config_obj, 1, esp_config);
|
||||
|
||||
STATIC const mp_rom_map_elem_t wlan_if_locals_dict_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR_active), MP_ROM_PTR(&esp_active_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_connect), MP_ROM_PTR(&esp_connect_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_disconnect), MP_ROM_PTR(&esp_disconnect_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_status), MP_ROM_PTR(&esp_status_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_scan), MP_ROM_PTR(&esp_scan_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_isconnected), MP_ROM_PTR(&esp_isconnected_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_config), MP_ROM_PTR(&esp_config_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_ifconfig), MP_ROM_PTR(&esp_ifconfig_obj) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(wlan_if_locals_dict, wlan_if_locals_dict_table);
|
||||
|
||||
const mp_obj_type_t wlan_if_type = {
|
||||
{ &mp_type_type },
|
||||
.name = MP_QSTR_WLAN,
|
||||
.locals_dict = (mp_obj_dict_t*)&wlan_if_locals_dict,
|
||||
};
|
||||
|
||||
STATIC mp_obj_t esp_phy_mode(size_t n_args, const mp_obj_t *args) {
|
||||
if (n_args == 0) {
|
||||
return mp_obj_new_int(wifi_get_phy_mode());
|
||||
} else {
|
||||
wifi_set_phy_mode(mp_obj_get_int(args[0]));
|
||||
return mp_const_none;
|
||||
}
|
||||
}
|
||||
STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(esp_phy_mode_obj, 0, 1, esp_phy_mode);
|
||||
|
||||
STATIC const mp_rom_map_elem_t mp_module_network_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_network) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_WLAN), MP_ROM_PTR(&get_wlan_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_phy_mode), MP_ROM_PTR(&esp_phy_mode_obj) },
|
||||
|
||||
#if MODNETWORK_INCLUDE_CONSTANTS
|
||||
{ MP_ROM_QSTR(MP_QSTR_STA_IF), MP_ROM_INT(STATION_IF)},
|
||||
{ MP_ROM_QSTR(MP_QSTR_AP_IF), MP_ROM_INT(SOFTAP_IF)},
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_STAT_IDLE), MP_ROM_INT(STATION_IDLE)},
|
||||
{ MP_ROM_QSTR(MP_QSTR_STAT_CONNECTING), MP_ROM_INT(STATION_CONNECTING)},
|
||||
{ MP_ROM_QSTR(MP_QSTR_STAT_WRONG_PASSWORD), MP_ROM_INT(STATION_WRONG_PASSWORD)},
|
||||
{ MP_ROM_QSTR(MP_QSTR_STAT_NO_AP_FOUND), MP_ROM_INT(STATION_NO_AP_FOUND)},
|
||||
{ MP_ROM_QSTR(MP_QSTR_STAT_CONNECT_FAIL), MP_ROM_INT(STATION_CONNECT_FAIL)},
|
||||
{ MP_ROM_QSTR(MP_QSTR_STAT_GOT_IP), MP_ROM_INT(STATION_GOT_IP)},
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_MODE_11B), MP_ROM_INT(PHY_MODE_11B) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_MODE_11G), MP_ROM_INT(PHY_MODE_11G) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_MODE_11N), MP_ROM_INT(PHY_MODE_11N) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_AUTH_OPEN), MP_ROM_INT(AUTH_OPEN) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_AUTH_WEP), MP_ROM_INT(AUTH_WEP) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_AUTH_WPA_PSK), MP_ROM_INT(AUTH_WPA_PSK) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_AUTH_WPA2_PSK), MP_ROM_INT(AUTH_WPA2_PSK) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_AUTH_WPA_WPA2_PSK), MP_ROM_INT(AUTH_WPA_WPA2_PSK) },
|
||||
#endif
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(mp_module_network_globals, mp_module_network_globals_table);
|
||||
|
||||
const mp_obj_module_t network_module = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t*)&mp_module_network_globals,
|
||||
};
|
@ -1,79 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014 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/gc.h"
|
||||
#include "gccollect.h"
|
||||
#include "modmachine.h"
|
||||
|
||||
// The pyb module no longer exists since all functionality now appears
|
||||
// elsewhere, in more standard places (eg time, machine modules). The
|
||||
// only remaining function is pyb.info() which has been moved to the
|
||||
// esp module, pending deletion/renaming/moving elsewhere.
|
||||
|
||||
STATIC mp_obj_t pyb_info(size_t n_args, const mp_obj_t *args) {
|
||||
// print info about memory
|
||||
{
|
||||
printf("_text_start=%p\n", &_text_start);
|
||||
printf("_text_end=%p\n", &_text_end);
|
||||
printf("_irom0_text_start=%p\n", &_irom0_text_start);
|
||||
printf("_irom0_text_end=%p\n", &_irom0_text_end);
|
||||
printf("_data_start=%p\n", &_data_start);
|
||||
printf("_data_end=%p\n", &_data_end);
|
||||
printf("_rodata_start=%p\n", &_rodata_start);
|
||||
printf("_rodata_end=%p\n", &_rodata_end);
|
||||
printf("_bss_start=%p\n", &_bss_start);
|
||||
printf("_bss_end=%p\n", &_bss_end);
|
||||
printf("_heap_start=%p\n", &_heap_start);
|
||||
printf("_heap_end=%p\n", &_heap_end);
|
||||
}
|
||||
|
||||
// qstr info
|
||||
{
|
||||
mp_uint_t n_pool, n_qstr, n_str_data_bytes, n_total_bytes;
|
||||
qstr_pool_info(&n_pool, &n_qstr, &n_str_data_bytes, &n_total_bytes);
|
||||
printf("qstr:\n n_pool=" UINT_FMT "\n n_qstr=" UINT_FMT "\n n_str_data_bytes=" UINT_FMT "\n n_total_bytes=" UINT_FMT "\n", n_pool, n_qstr, n_str_data_bytes, n_total_bytes);
|
||||
}
|
||||
|
||||
// GC info
|
||||
{
|
||||
gc_info_t info;
|
||||
gc_info(&info);
|
||||
printf("GC:\n");
|
||||
printf(" " UINT_FMT " total\n", info.total);
|
||||
printf(" " UINT_FMT " : " UINT_FMT "\n", info.used, info.free);
|
||||
printf(" 1=" UINT_FMT " 2=" UINT_FMT " m=" UINT_FMT "\n", info.num_1block, info.num_2block, info.max_block);
|
||||
}
|
||||
|
||||
if (n_args == 1) {
|
||||
// arg given means dump gc allocation table
|
||||
gc_dump_alloc_table();
|
||||
}
|
||||
|
||||
return mp_const_none;
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_info_obj, 0, 1, pyb_info);
|
@ -1,14 +0,0 @@
|
||||
import gc
|
||||
gc.threshold((gc.mem_free() + gc.mem_alloc()) // 4)
|
||||
from flashbdev import bdev
|
||||
import storage
|
||||
|
||||
try:
|
||||
if bdev:
|
||||
vfs = storage.VfsFat(bdev)
|
||||
storage.mount(vfs, '/')
|
||||
except OSError:
|
||||
import inisetup
|
||||
inisetup.setup()
|
||||
|
||||
gc.collect()
|
@ -1,35 +0,0 @@
|
||||
import esp
|
||||
|
||||
class FlashBdev:
|
||||
|
||||
SEC_SIZE = 4096
|
||||
RESERVED_SECS = 1
|
||||
START_SEC = esp.flash_user_start() // SEC_SIZE + RESERVED_SECS
|
||||
NUM_BLK = 0x6b - RESERVED_SECS
|
||||
|
||||
def __init__(self, blocks=NUM_BLK):
|
||||
self.blocks = blocks
|
||||
|
||||
def readblocks(self, n, buf):
|
||||
#print("readblocks(%s, %x(%d))" % (n, id(buf), len(buf)))
|
||||
esp.flash_read((n + self.START_SEC) * self.SEC_SIZE, buf)
|
||||
|
||||
def writeblocks(self, n, buf):
|
||||
#print("writeblocks(%s, %x(%d))" % (n, id(buf), len(buf)))
|
||||
#assert len(buf) <= self.SEC_SIZE, len(buf)
|
||||
esp.flash_erase(n + self.START_SEC)
|
||||
esp.flash_write((n + self.START_SEC) * self.SEC_SIZE, buf)
|
||||
|
||||
def ioctl(self, op, arg):
|
||||
#print("ioctl(%d, %r)" % (op, arg))
|
||||
if op == 4: # BP_IOCTL_SEC_COUNT
|
||||
return self.blocks
|
||||
if op == 5: # BP_IOCTL_SEC_SIZE
|
||||
return self.SEC_SIZE
|
||||
|
||||
size = esp.flash_size()
|
||||
if size < 1024*1024:
|
||||
bdev = None
|
||||
else:
|
||||
# 20K at the flash end is reserved for SDK params storage
|
||||
bdev = FlashBdev((size - 20480) // FlashBdev.SEC_SIZE - FlashBdev.START_SEC)
|
@ -1,56 +0,0 @@
|
||||
from flashbdev import bdev
|
||||
import network
|
||||
import storage
|
||||
|
||||
def wifi():
|
||||
try:
|
||||
import ubinascii as binascii
|
||||
except ImportError:
|
||||
import binascii
|
||||
|
||||
ap_if = network.WLAN(network.AP_IF)
|
||||
essid = b"MicroPython-%s" % binascii.hexlify(ap_if.config("mac")[-3:])
|
||||
ap_if.config(essid=essid, authmode=network.AUTH_WPA_WPA2_PSK, password=b"micropythoN")
|
||||
|
||||
def check_bootsec():
|
||||
buf = bytearray(bdev.SEC_SIZE)
|
||||
bdev.readblocks(0, buf)
|
||||
empty = True
|
||||
for b in buf:
|
||||
if b != 0xff:
|
||||
empty = False
|
||||
break
|
||||
if empty:
|
||||
return True
|
||||
fs_corrupted()
|
||||
|
||||
def fs_corrupted():
|
||||
import time
|
||||
while 1:
|
||||
print("""\
|
||||
The FAT filesystem starting at sector %d with size %d sectors appears to
|
||||
be corrupted. If you had important data there, you may want to make a flash
|
||||
snapshot to try to recover it. Otherwise, perform factory reprogramming
|
||||
of MicroPython firmware (completely erase flash, followed by firmware
|
||||
programming).
|
||||
""" % (bdev.START_SEC, bdev.blocks))
|
||||
time.sleep(3)
|
||||
|
||||
def setup():
|
||||
check_bootsec()
|
||||
print("Performing initial setup")
|
||||
wifi()
|
||||
storage.VfsFat.mkfs(bdev)
|
||||
vfs = storage.VfsFat(bdev)
|
||||
storage.mount(vfs, '/')
|
||||
with open("boot.py", "w") as f:
|
||||
f.write("""\
|
||||
# This file is executed on every boot (including wake-boot from deepsleep)
|
||||
#import esp
|
||||
#esp.osdebug(None)
|
||||
import gc
|
||||
#import webrepl
|
||||
#webrepl.start()
|
||||
gc.collect()
|
||||
""")
|
||||
return vfs
|
@ -1,35 +0,0 @@
|
||||
try:
|
||||
import usocket as socket
|
||||
except:
|
||||
import socket
|
||||
try:
|
||||
import ustruct as struct
|
||||
except:
|
||||
import struct
|
||||
|
||||
# (date(2000, 1, 1) - date(1900, 1, 1)).days * 24*60*60
|
||||
NTP_DELTA = 3155673600
|
||||
|
||||
host = "pool.ntp.org"
|
||||
|
||||
def time():
|
||||
NTP_QUERY = bytearray(48)
|
||||
NTP_QUERY[0] = 0x1b
|
||||
addr = socket.getaddrinfo(host, 123)[0][-1]
|
||||
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
|
||||
s.settimeout(1)
|
||||
res = s.sendto(NTP_QUERY, addr)
|
||||
msg = s.recv(48)
|
||||
s.close()
|
||||
val = struct.unpack("!I", msg[40:44])[0]
|
||||
return val - NTP_DELTA
|
||||
|
||||
# There's currently no timezone support in MicroPython, so
|
||||
# utime.localtime() will return UTC time (as if it was .gmtime())
|
||||
def settime():
|
||||
t = time()
|
||||
import machine
|
||||
import utime
|
||||
tm = utime.localtime(t)
|
||||
tm = tm[0:3] + (0,) + tm[3:6] + (0,)
|
||||
machine.RTC().datetime(tm)
|
@ -1,33 +0,0 @@
|
||||
import esp
|
||||
import uctypes
|
||||
import network
|
||||
import lwip
|
||||
|
||||
|
||||
def main():
|
||||
|
||||
ROM = uctypes.bytearray_at(0x40200000, 16)
|
||||
fid = esp.flash_id()
|
||||
|
||||
print("FlashROM:")
|
||||
print("Flash ID: %x (Vendor: %x Device: %x)" % (fid, fid & 0xff, fid & 0xff00 | fid >> 16))
|
||||
|
||||
print("Flash bootloader data:")
|
||||
SZ_MAP = {0: "512KB", 1: "256KB", 2: "1MB", 3: "2MB", 4: "4MB"}
|
||||
FREQ_MAP = {0: "40MHZ", 1: "26MHZ", 2: "20MHz", 0xf: "80MHz"}
|
||||
print("Byte @2: %02x" % ROM[2])
|
||||
print("Byte @3: %02x (Flash size: %s Flash freq: %s)" % (ROM[3], SZ_MAP.get(ROM[3] >> 4, "?"), FREQ_MAP.get(ROM[3] & 0xf)))
|
||||
print("Firmware checksum:")
|
||||
print(esp.check_fw())
|
||||
|
||||
print("\nNetworking:")
|
||||
print("STA ifconfig:", network.WLAN(network.STA_IF).ifconfig())
|
||||
print("AP ifconfig:", network.WLAN(network.AP_IF).ifconfig())
|
||||
print("Free WiFi driver buffers of type:")
|
||||
for i, comm in enumerate(("1,2 TX", "4 Mngmt TX(len: 0x41-0x100)", "5 Mngmt TX (len: 0-0x40)", "7", "8 RX")):
|
||||
print("%d: %d (%s)" % (i, esp.esf_free_bufs(i), comm))
|
||||
print("lwIP PCBs:")
|
||||
lwip.print_pcbs()
|
||||
|
||||
|
||||
main()
|
@ -1 +0,0 @@
|
||||
../../../tools/upip.py
|
@ -1 +0,0 @@
|
||||
../../../tools/upip_utarfile.py
|
@ -1,77 +0,0 @@
|
||||
# This module should be imported from REPL, not run from command line.
|
||||
import socket
|
||||
import multiterminal
|
||||
import network
|
||||
import websocket
|
||||
import websocket_helper
|
||||
import _webrepl
|
||||
|
||||
listen_s = None
|
||||
client_s = None
|
||||
|
||||
def setup_conn(port, accept_handler):
|
||||
global listen_s
|
||||
listen_s = socket.socket()
|
||||
listen_s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
|
||||
|
||||
ai = socket.getaddrinfo("0.0.0.0", port)
|
||||
addr = ai[0][4]
|
||||
|
||||
listen_s.bind(addr)
|
||||
listen_s.listen(1)
|
||||
if accept_handler:
|
||||
listen_s.setsockopt(socket.SOL_SOCKET, 20, accept_handler)
|
||||
for i in (network.AP_IF, network.STA_IF):
|
||||
iface = network.WLAN(i)
|
||||
if iface.active():
|
||||
print("WebREPL daemon started on ws://%s:%d" % (iface.ifconfig()[0], port))
|
||||
return listen_s
|
||||
|
||||
|
||||
def accept_conn(listen_sock):
|
||||
global client_s
|
||||
cl, remote_addr = listen_sock.accept()
|
||||
if multiterminal.get_secondary_terminal():
|
||||
print("\nConcurrent WebREPL connection from", remote_addr, "rejected")
|
||||
cl.close()
|
||||
return
|
||||
print("\nWebREPL connection from:", remote_addr)
|
||||
client_s = cl
|
||||
websocket_helper.server_handshake(cl)
|
||||
ws = websocket.websocket(cl, True)
|
||||
ws = _webrepl._webrepl(ws)
|
||||
cl.setblocking(False)
|
||||
# notify REPL on socket incoming data
|
||||
cl.setsockopt(socket.SOL_SOCKET, 20, multiterminal.schedule_secondary_terminal_read)
|
||||
multiterminal.set_secondary_terminal(ws)
|
||||
|
||||
|
||||
def stop():
|
||||
global listen_s, client_s
|
||||
multiterminal.clear_secondary_terminal()
|
||||
if client_s:
|
||||
client_s.close()
|
||||
if listen_s:
|
||||
listen_s.close()
|
||||
|
||||
|
||||
def start(port=8266, password=None):
|
||||
stop()
|
||||
if password is None:
|
||||
try:
|
||||
import webrepl_cfg
|
||||
_webrepl.password(webrepl_cfg.PASS)
|
||||
setup_conn(port, accept_conn)
|
||||
print("Started webrepl in normal mode")
|
||||
except:
|
||||
print("WebREPL is not configured, run 'import webrepl_setup'")
|
||||
else:
|
||||
_webrepl.password(password)
|
||||
setup_conn(port, accept_conn)
|
||||
print("Started webrepl in manual override mode")
|
||||
|
||||
|
||||
def start_foreground(port=8266):
|
||||
stop()
|
||||
s = setup_conn(port, None)
|
||||
accept_conn(s)
|
@ -1,112 +0,0 @@
|
||||
import sys
|
||||
import os
|
||||
import machine
|
||||
|
||||
RC = "./boot.py"
|
||||
CONFIG = "./webrepl_cfg.py"
|
||||
|
||||
def input_choice(prompt, choices):
|
||||
while 1:
|
||||
resp = input(prompt)
|
||||
if resp in choices:
|
||||
return resp
|
||||
|
||||
def getpass(prompt):
|
||||
return input(prompt)
|
||||
|
||||
def input_pass():
|
||||
while 1:
|
||||
passwd1 = getpass("New password (4-9 chars): ")
|
||||
if len(passwd1) < 4 or len(passwd1) > 9:
|
||||
print("Invalid password length")
|
||||
continue
|
||||
passwd2 = getpass("Confirm password: ")
|
||||
if passwd1 == passwd2:
|
||||
return passwd1
|
||||
print("Passwords do not match")
|
||||
|
||||
|
||||
def exists(fname):
|
||||
try:
|
||||
with open(fname):
|
||||
pass
|
||||
return True
|
||||
except OSError:
|
||||
return False
|
||||
|
||||
def copy_stream(s_in, s_out):
|
||||
buf = bytearray(64)
|
||||
while 1:
|
||||
sz = s_in.readinto(buf)
|
||||
s_out.write(buf, sz)
|
||||
|
||||
|
||||
def get_daemon_status():
|
||||
with open(RC) as f:
|
||||
for l in f:
|
||||
if "webrepl" in l:
|
||||
if l.startswith("#"):
|
||||
return False
|
||||
return True
|
||||
return None
|
||||
|
||||
def add_daemon():
|
||||
with open(RC) as old_f, open(RC + ".tmp", "w") as new_f:
|
||||
new_f.write("import webrepl\nwebrepl.start()\n")
|
||||
copy_stream(old_f, new_f)
|
||||
|
||||
def change_daemon(action):
|
||||
LINES = ("import webrepl", "webrepl.start()")
|
||||
with open(RC) as old_f, open(RC + ".tmp", "w") as new_f:
|
||||
found = False
|
||||
for l in old_f:
|
||||
for patt in LINES:
|
||||
if patt in l:
|
||||
found = True
|
||||
if action and l.startswith("#"):
|
||||
l = l[1:]
|
||||
elif not action and not l.startswith("#"):
|
||||
l = "#" + l
|
||||
new_f.write(l)
|
||||
if not found:
|
||||
new_f.write("import webrepl\nwebrepl.start()\n")
|
||||
# FatFs rename() is not POSIX compliant, will raise OSError if
|
||||
# dest file exists.
|
||||
os.remove(RC)
|
||||
os.rename(RC + ".tmp", RC)
|
||||
|
||||
|
||||
def main():
|
||||
status = get_daemon_status()
|
||||
|
||||
print("WebREPL daemon auto-start status:", "enabled" if status else "disabled")
|
||||
print("\nWould you like to (E)nable or (D)isable it running on boot?")
|
||||
print("(Empty line to quit)")
|
||||
resp = input("> ").upper()
|
||||
|
||||
if resp == "E":
|
||||
if exists(CONFIG):
|
||||
resp2 = input_choice("Would you like to change WebREPL password? (y/n) ", ("y", "n", ""))
|
||||
else:
|
||||
print("To enable WebREPL, you must set password for it")
|
||||
resp2 = "y"
|
||||
|
||||
if resp2 == "y":
|
||||
passwd = input_pass()
|
||||
with open(CONFIG, "w") as f:
|
||||
f.write("PASS = %r\n" % passwd)
|
||||
|
||||
|
||||
if resp not in ("D", "E") or (resp == "D" and not status) or (resp == "E" and status):
|
||||
print("No further action required")
|
||||
sys.exit()
|
||||
|
||||
change_daemon(resp == "E")
|
||||
|
||||
print("Changes will be activated after reboot")
|
||||
resp = input_choice("Would you like to reboot now? (y/n) ", ("y", "n", ""))
|
||||
if resp == "y":
|
||||
print("Rebooting. Please manually reset if it hangs.")
|
||||
machine.reset()
|
||||
|
||||
main()
|
@ -1,74 +0,0 @@
|
||||
import sys
|
||||
try:
|
||||
import ubinascii as binascii
|
||||
except:
|
||||
import binascii
|
||||
try:
|
||||
import uhashlib as hashlib
|
||||
except:
|
||||
import hashlib
|
||||
|
||||
DEBUG = 0
|
||||
|
||||
def server_handshake(sock):
|
||||
clr = sock.makefile("rwb", 0)
|
||||
l = clr.readline()
|
||||
#sys.stdout.write(repr(l))
|
||||
|
||||
webkey = None
|
||||
|
||||
while 1:
|
||||
l = clr.readline()
|
||||
if not l:
|
||||
raise OSError("EOF in headers")
|
||||
if l == b"\r\n":
|
||||
break
|
||||
# sys.stdout.write(l)
|
||||
h, v = [x.strip() for x in l.split(b":", 1)]
|
||||
if DEBUG:
|
||||
print((h, v))
|
||||
if h == b'Sec-WebSocket-Key':
|
||||
webkey = v
|
||||
|
||||
if not webkey:
|
||||
raise OSError("Not a websocket request")
|
||||
|
||||
if DEBUG:
|
||||
print("Sec-WebSocket-Key:", webkey, len(webkey))
|
||||
|
||||
d = hashlib.sha1(webkey)
|
||||
d.update(b"258EAFA5-E914-47DA-95CA-C5AB0DC85B11")
|
||||
respkey = d.digest()
|
||||
respkey = binascii.b2a_base64(respkey)[:-1]
|
||||
if DEBUG:
|
||||
print("respkey:", respkey)
|
||||
|
||||
sock.send(b"""\
|
||||
HTTP/1.1 101 Switching Protocols\r
|
||||
Upgrade: websocket\r
|
||||
Connection: Upgrade\r
|
||||
Sec-WebSocket-Accept: """)
|
||||
sock.send(respkey)
|
||||
sock.send("\r\n\r\n")
|
||||
|
||||
|
||||
# Very simplified client handshake, works for MicroPython's
|
||||
# websocket server implementation, but probably not for other
|
||||
# servers.
|
||||
def client_handshake(sock):
|
||||
cl = sock.makefile("rwb", 0)
|
||||
cl.write(b"""\
|
||||
GET / HTTP/1.1\r
|
||||
Host: echo.websocket.org\r
|
||||
Connection: Upgrade\r
|
||||
Upgrade: websocket\r
|
||||
Sec-WebSocket-Key: foo\r
|
||||
\r
|
||||
""")
|
||||
l = cl.readline()
|
||||
# print(l)
|
||||
while 1:
|
||||
l = cl.readline()
|
||||
if l == b"\r\n":
|
||||
break
|
||||
# sys.stdout.write(l)
|
@ -1,129 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2013, 2014 Damien P. George
|
||||
* Copyright (c) 2015 Josef Gajdusek
|
||||
*
|
||||
* 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/gc.h"
|
||||
#include "py/runtime.h"
|
||||
#include "py/mphal.h"
|
||||
#include "py/smallint.h"
|
||||
#include "lib/timeutils/timeutils.h"
|
||||
#include "modmachine.h"
|
||||
#include "user_interface.h"
|
||||
#include "extmod/utime_mphal.h"
|
||||
|
||||
/// \module time - time related functions
|
||||
///
|
||||
/// The `time` module provides functions for getting the current time and date,
|
||||
/// and for sleeping.
|
||||
|
||||
/// \function localtime([secs])
|
||||
/// Convert a time expressed in seconds since Jan 1, 2000 into an 8-tuple which
|
||||
/// contains: (year, month, mday, hour, minute, second, weekday, yearday)
|
||||
/// If secs is not provided or None, then the current time from the RTC is used.
|
||||
/// year includes the century (for example 2014)
|
||||
/// month is 1-12
|
||||
/// mday is 1-31
|
||||
/// hour is 0-23
|
||||
/// minute is 0-59
|
||||
/// second is 0-59
|
||||
/// weekday is 0-6 for Mon-Sun.
|
||||
/// yearday is 1-366
|
||||
STATIC mp_obj_t time_localtime(size_t n_args, const mp_obj_t *args) {
|
||||
timeutils_struct_time_t tm;
|
||||
mp_int_t seconds;
|
||||
if (n_args == 0 || args[0] == mp_const_none) {
|
||||
seconds = pyb_rtc_get_us_since_2000() / 1000 / 1000;
|
||||
} else {
|
||||
seconds = mp_obj_get_int(args[0]);
|
||||
}
|
||||
timeutils_seconds_since_2000_to_struct_time(seconds, &tm);
|
||||
mp_obj_t tuple[8] = {
|
||||
tuple[0] = mp_obj_new_int(tm.tm_year),
|
||||
tuple[1] = mp_obj_new_int(tm.tm_mon),
|
||||
tuple[2] = mp_obj_new_int(tm.tm_mday),
|
||||
tuple[3] = mp_obj_new_int(tm.tm_hour),
|
||||
tuple[4] = mp_obj_new_int(tm.tm_min),
|
||||
tuple[5] = mp_obj_new_int(tm.tm_sec),
|
||||
tuple[6] = mp_obj_new_int(tm.tm_wday),
|
||||
tuple[7] = mp_obj_new_int(tm.tm_yday),
|
||||
};
|
||||
return mp_obj_new_tuple(8, tuple);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(time_localtime_obj, 0, 1, time_localtime);
|
||||
|
||||
/// \function mktime()
|
||||
/// This is inverse function of localtime. It's argument is a full 8-tuple
|
||||
/// which expresses a time as per localtime. It returns an integer which is
|
||||
/// the number of seconds since Jan 1, 2000.
|
||||
STATIC mp_obj_t time_mktime(mp_obj_t tuple) {
|
||||
size_t len;
|
||||
mp_obj_t *elem;
|
||||
mp_obj_get_array(tuple, &len, &elem);
|
||||
|
||||
// localtime generates a tuple of len 8. CPython uses 9, so we accept both.
|
||||
if (len < 8 || len > 9) {
|
||||
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "mktime needs a tuple of length 8 or 9 (%d given)", len));
|
||||
}
|
||||
|
||||
return mp_obj_new_int_from_uint(timeutils_mktime(mp_obj_get_int(elem[0]),
|
||||
mp_obj_get_int(elem[1]), mp_obj_get_int(elem[2]), mp_obj_get_int(elem[3]),
|
||||
mp_obj_get_int(elem[4]), mp_obj_get_int(elem[5])));
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_1(time_mktime_obj, time_mktime);
|
||||
|
||||
/// \function time()
|
||||
/// Returns the number of seconds, as an integer, since 1/1/2000.
|
||||
STATIC mp_obj_t time_time(void) {
|
||||
// get date and time
|
||||
return mp_obj_new_int(pyb_rtc_get_us_since_2000() / 1000 / 1000);
|
||||
}
|
||||
MP_DEFINE_CONST_FUN_OBJ_0(time_time_obj, time_time);
|
||||
|
||||
STATIC const mp_rom_map_elem_t time_module_globals_table[] = {
|
||||
{ MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_utime) },
|
||||
|
||||
{ MP_ROM_QSTR(MP_QSTR_localtime), MP_ROM_PTR(&time_localtime_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_mktime), MP_ROM_PTR(&time_mktime_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_sleep), MP_ROM_PTR(&mp_utime_sleep_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_sleep_ms), MP_ROM_PTR(&mp_utime_sleep_ms_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_sleep_us), MP_ROM_PTR(&mp_utime_sleep_us_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_ticks_ms), MP_ROM_PTR(&mp_utime_ticks_ms_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_ticks_us), MP_ROM_PTR(&mp_utime_ticks_us_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_ticks_cpu), MP_ROM_PTR(&mp_utime_ticks_cpu_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_ticks_add), MP_ROM_PTR(&mp_utime_ticks_add_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_ticks_diff), MP_ROM_PTR(&mp_utime_ticks_diff_obj) },
|
||||
{ MP_ROM_QSTR(MP_QSTR_time), MP_ROM_PTR(&time_time_obj) },
|
||||
};
|
||||
|
||||
STATIC MP_DEFINE_CONST_DICT(time_module_globals, time_module_globals_table);
|
||||
|
||||
const mp_obj_module_t utime_module = {
|
||||
.base = { &mp_type_module },
|
||||
.globals = (mp_obj_dict_t*)&time_module_globals,
|
||||
};
|
@ -1,227 +0,0 @@
|
||||
#include <stdint.h>
|
||||
|
||||
// options to control how MicroPython is built
|
||||
|
||||
#define MICROPY_OBJ_REPR (MICROPY_OBJ_REPR_C)
|
||||
#define MICROPY_ALLOC_PATH_MAX (128)
|
||||
#define MICROPY_ALLOC_LEXER_INDENT_INIT (8)
|
||||
#define MICROPY_ALLOC_PARSE_RULE_INIT (48)
|
||||
#define MICROPY_ALLOC_PARSE_RULE_INC (8)
|
||||
#define MICROPY_ALLOC_PARSE_RESULT_INC (8)
|
||||
#define MICROPY_ALLOC_PARSE_CHUNK_INIT (64)
|
||||
#define MICROPY_PERSISTENT_CODE_LOAD (1)
|
||||
#define MICROPY_EMIT_XTENSA (1)
|
||||
#define MICROPY_EMIT_INLINE_XTENSA (1)
|
||||
#define MICROPY_MEM_STATS (0)
|
||||
#define MICROPY_DEBUG_PRINTERS (1)
|
||||
#define MICROPY_DEBUG_PRINTER_DEST mp_debug_print
|
||||
#define MICROPY_READER_VFS (MICROPY_VFS)
|
||||
#define MICROPY_ENABLE_GC (1)
|
||||
#define MICROPY_ENABLE_FINALISER (1)
|
||||
#define MICROPY_STACK_CHECK (1)
|
||||
#define MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF (1)
|
||||
#define MICROPY_KBD_EXCEPTION (1)
|
||||
#define MICROPY_REPL_EVENT_DRIVEN (0)
|
||||
#define MICROPY_REPL_AUTO_INDENT (1)
|
||||
#define MICROPY_HELPER_REPL (1)
|
||||
#define MICROPY_HELPER_LEXER_UNIX (0)
|
||||
#define MICROPY_ENABLE_SOURCE_LINE (1)
|
||||
#define MICROPY_MODULE_WEAK_LINKS (1)
|
||||
#define MICROPY_CAN_OVERRIDE_BUILTINS (1)
|
||||
#define MICROPY_USE_INTERNAL_ERRNO (0)
|
||||
#define MICROPY_ENABLE_SCHEDULER (1)
|
||||
#define MICROPY_PY_DESCRIPTORS (1)
|
||||
#define MICROPY_PY_ALL_SPECIAL_METHODS (1)
|
||||
#define MICROPY_PY_BUILTINS_COMPLEX (0)
|
||||
#define MICROPY_PY_BUILTINS_STR_UNICODE (1)
|
||||
#define MICROPY_PY_BUILTINS_BYTEARRAY (1)
|
||||
#define MICROPY_PY_BUILTINS_MEMORYVIEW (1)
|
||||
#define MICROPY_PY_BUILTINS_FROZENSET (1)
|
||||
#define MICROPY_PY_BUILTINS_SET (1)
|
||||
#define MICROPY_PY_BUILTINS_SLICE (1)
|
||||
#define MICROPY_PY_BUILTINS_SLICE_ATTRS (1)
|
||||
#define MICROPY_PY_BUILTINS_PROPERTY (1)
|
||||
#define MICROPY_PY_BUILTINS_ROUND_INT (1)
|
||||
#define MICROPY_PY_BUILTINS_INPUT (1)
|
||||
#define MICROPY_PY_BUILTINS_HELP (1)
|
||||
#define MICROPY_PY_BUILTINS_HELP_TEXT esp_help_text
|
||||
#define MICROPY_PY_BUILTINS_HELP_MODULES (1)
|
||||
#define MICROPY_PY___FILE__ (0)
|
||||
#define MICROPY_PY_GC (1)
|
||||
#define MICROPY_PY_ARRAY (1)
|
||||
#define MICROPY_PY_ARRAY_SLICE_ASSIGN (1)
|
||||
#define MICROPY_NONSTANDARD_TYPECODES (0)
|
||||
#define MICROPY_PY_COLLECTIONS (1)
|
||||
#define MICROPY_PY_COLLECTIONS_DEQUE (1)
|
||||
#define MICROPY_PY_COLLECTIONS_ORDEREDDICT (1)
|
||||
#define MICROPY_PY_MATH (0)
|
||||
#define MICROPY_PY_CMATH (0)
|
||||
#define MICROPY_PY_IO (1)
|
||||
#define MICROPY_PY_IO_IOBASE (1)
|
||||
#define MICROPY_PY_IO_FILEIO (1)
|
||||
#define MICROPY_PY_STRUCT (0)
|
||||
#define MICROPY_PY_SYS (1)
|
||||
#define MICROPY_PY_SYS_MAXSIZE (1)
|
||||
#define MICROPY_PY_SYS_EXIT (1)
|
||||
#define MICROPY_PY_SYS_STDFILES (1)
|
||||
#define MICROPY_PY_SYS_STDIO_BUFFER (1)
|
||||
#define MICROPY_PY_UERRNO (1)
|
||||
#define MICROPY_PY_UBINASCII (1)
|
||||
#define MICROPY_PY_UCTYPES (1)
|
||||
#define MICROPY_PY_UHASHLIB (1)
|
||||
#define MICROPY_PY_UHASHLIB_SHA1 (MICROPY_PY_USSL && MICROPY_SSL_AXTLS)
|
||||
#define MICROPY_PY_UHEAPQ (1)
|
||||
#define MICROPY_PY_UTIMEQ (1)
|
||||
#define MICROPY_PY_UJSON (1)
|
||||
#define MICROPY_PY_URANDOM (0)
|
||||
#define MICROPY_PY_URE (1)
|
||||
#define MICROPY_PY_USELECT (1)
|
||||
#define MICROPY_PY_UTIME_MP_HAL (1)
|
||||
#define MICROPY_PY_UZLIB (1)
|
||||
#define MICROPY_PY_LWIP (1)
|
||||
#define MICROPY_PY_MACHINE (1)
|
||||
#define MICROPY_PY_MACHINE_PIN_MAKE_NEW mp_pin_make_new
|
||||
#define MICROPY_PY_MACHINE_PULSE (1)
|
||||
#define MICROPY_PY_MACHINE_I2C (1)
|
||||
#define MICROPY_PY_MACHINE_SPI (1)
|
||||
#define MICROPY_PY_MACHINE_SPI_MAKE_NEW machine_hspi_make_new
|
||||
#define MICROPY_PY_WEBSOCKET (1)
|
||||
#define MICROPY_PY_WEBREPL (1)
|
||||
#define MICROPY_PY_WEBREPL_DELAY (20)
|
||||
#define MICROPY_PY_FRAMEBUF (1)
|
||||
#define MICROPY_PY_MICROPYTHON_MEM_INFO (1)
|
||||
#define MICROPY_PY_OS_DUPTERM (2)
|
||||
#define MICROPY_CPYTHON_COMPAT (1)
|
||||
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_MPZ)
|
||||
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_FLOAT)
|
||||
#define MICROPY_FLOAT_HIGH_QUALITY_HASH (1)
|
||||
#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_NORMAL)
|
||||
#define MICROPY_WARNINGS (1)
|
||||
#define MICROPY_PY_STR_BYTES_CMP_WARN (1)
|
||||
#define MICROPY_STREAMS_NON_BLOCK (1)
|
||||
#define MICROPY_STREAMS_POSIX_API (1)
|
||||
#define MICROPY_MODULE_FROZEN_STR (1)
|
||||
#define MICROPY_MODULE_FROZEN_MPY (1)
|
||||
#define MICROPY_MODULE_FROZEN_LEXER mp_lexer_new_from_str32
|
||||
#define MICROPY_QSTR_EXTRA_POOL mp_qstr_frozen_const_pool
|
||||
|
||||
#define MICROPY_VFS (1)
|
||||
#define MICROPY_FATFS_ENABLE_LFN (1)
|
||||
#define MICROPY_FATFS_RPATH (2)
|
||||
#define MICROPY_FATFS_MAX_SS (4096)
|
||||
#define MICROPY_FATFS_LFN_CODE_PAGE (437) /* 1=SFN/ANSI 437=LFN/U.S.(OEM) */
|
||||
#define MICROPY_VFS_FAT (1)
|
||||
#define MICROPY_ESP8266_NEOPIXEL (1)
|
||||
|
||||
extern void ets_event_poll(void);
|
||||
#define MICROPY_EVENT_POLL_HOOK {ets_event_poll();}
|
||||
#define MICROPY_VM_HOOK_COUNT (10)
|
||||
#define MICROPY_VM_HOOK_INIT static uint vm_hook_divisor = MICROPY_VM_HOOK_COUNT;
|
||||
#define MICROPY_VM_HOOK_POLL if (--vm_hook_divisor == 0) { \
|
||||
vm_hook_divisor = MICROPY_VM_HOOK_COUNT; \
|
||||
extern void ets_loop_iter(void); \
|
||||
ets_loop_iter(); \
|
||||
}
|
||||
#define MICROPY_VM_HOOK_LOOP MICROPY_VM_HOOK_POLL
|
||||
#define MICROPY_VM_HOOK_RETURN MICROPY_VM_HOOK_POLL
|
||||
|
||||
// type definitions for the specific machine
|
||||
|
||||
#define MICROPY_MAKE_POINTER_CALLABLE(p) ((void*)((mp_uint_t)(p)))
|
||||
|
||||
#define MP_SSIZE_MAX (0x7fffffff)
|
||||
|
||||
#define UINT_FMT "%u"
|
||||
#define INT_FMT "%d"
|
||||
|
||||
typedef int32_t mp_int_t; // must be pointer size
|
||||
typedef uint32_t mp_uint_t; // must be pointer size
|
||||
typedef long mp_off_t;
|
||||
typedef uint32_t sys_prot_t; // for modlwip
|
||||
// ssize_t, off_t as required by POSIX-signatured functions in stream.h
|
||||
#include <sys/types.h>
|
||||
|
||||
#define MP_PLAT_PRINT_STRN(str, len) mp_hal_stdout_tx_strn_cooked(str, len)
|
||||
void *esp_native_code_commit(void*, size_t);
|
||||
#define MP_PLAT_COMMIT_EXEC(buf, len) esp_native_code_commit(buf, len)
|
||||
|
||||
#define mp_type_fileio mp_type_vfs_fat_fileio
|
||||
#define mp_type_textio mp_type_vfs_fat_textio
|
||||
|
||||
// use vfs's functions for import stat and builtin open
|
||||
#define mp_import_stat mp_vfs_import_stat
|
||||
#define mp_builtin_open mp_vfs_open
|
||||
#define mp_builtin_open_obj mp_vfs_open_obj
|
||||
|
||||
// extra built in names to add to the global namespace
|
||||
#define MICROPY_PORT_BUILTINS \
|
||||
{ MP_ROM_QSTR(MP_QSTR_open), MP_ROM_PTR(&mp_builtin_open_obj) },
|
||||
|
||||
// extra built in modules to add to the list of known ones
|
||||
extern const struct _mp_obj_module_t esp_module;
|
||||
extern const struct _mp_obj_module_t network_module;
|
||||
extern const struct _mp_obj_module_t os_module;
|
||||
extern const struct _mp_obj_module_t random_module;
|
||||
extern const struct _mp_obj_module_t struct_module;
|
||||
extern const struct _mp_obj_module_t mp_module_lwip;
|
||||
extern const struct _mp_obj_module_t mp_module_machine;
|
||||
extern const struct _mp_obj_module_t mp_module_onewire;
|
||||
extern const struct _mp_obj_module_t microcontroller_module;
|
||||
extern const struct _mp_obj_module_t board_module;
|
||||
extern const struct _mp_obj_module_t math_module;
|
||||
extern const struct _mp_obj_module_t analogio_module;
|
||||
extern const struct _mp_obj_module_t digitalio_module;
|
||||
extern const struct _mp_obj_module_t pulseio_module;
|
||||
extern const struct _mp_obj_module_t busio_module;
|
||||
extern const struct _mp_obj_module_t bitbangio_module;
|
||||
extern const struct _mp_obj_module_t time_module;
|
||||
extern const struct _mp_obj_module_t multiterminal_module;
|
||||
extern const struct _mp_obj_module_t neopixel_write_module;
|
||||
|
||||
#define MICROPY_PORT_BUILTIN_MODULES \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_esp), (mp_obj_t)&esp_module }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_socket), (mp_obj_t)&mp_module_lwip }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_usocket), (mp_obj_t)&mp_module_lwip }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_network), (mp_obj_t)&network_module }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_os), (mp_obj_t)&os_module }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_machine), (mp_obj_t)&mp_module_machine }, \
|
||||
{ MP_ROM_QSTR(MP_QSTR__onewire), MP_ROM_PTR(&mp_module_onewire) }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_microcontroller), (mp_obj_t)µcontroller_module }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_board), (mp_obj_t)&board_module }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_analogio), (mp_obj_t)&analogio_module }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_digitalio), (mp_obj_t)&digitalio_module }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_pulseio), (mp_obj_t)&pulseio_module }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_busio), (mp_obj_t)&busio_module }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_bitbangio), (mp_obj_t)&bitbangio_module }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_random), (mp_obj_t)&random_module }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_struct), (mp_obj_t)&struct_module }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_math), (mp_obj_t)&math_module }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_time), (mp_obj_t)&time_module }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_multiterminal), (mp_obj_t)&multiterminal_module }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_neopixel_write),(mp_obj_t)&neopixel_write_module }, \
|
||||
|
||||
#define MICROPY_PORT_BUILTIN_MODULE_WEAK_LINKS \
|
||||
{ MP_ROM_QSTR(MP_QSTR_json), MP_ROM_PTR(&mp_module_ujson) }, \
|
||||
{ MP_ROM_QSTR(MP_QSTR_errno), MP_ROM_PTR(&mp_module_uerrno) }, \
|
||||
{ MP_ROM_QSTR(MP_QSTR_select), MP_ROM_PTR(&mp_module_uselect) }, \
|
||||
{ MP_ROM_QSTR(MP_QSTR_socket), MP_ROM_PTR(&mp_module_lwip) }, \
|
||||
|
||||
#define MP_STATE_PORT MP_STATE_VM
|
||||
|
||||
#define MICROPY_PORT_ROOT_POINTERS \
|
||||
const char *readline_hist[8]; \
|
||||
mp_obj_t pin_irq_handler[16]; \
|
||||
|
||||
// We need to provide a declaration/definition of alloca()
|
||||
#include <alloca.h>
|
||||
|
||||
// board specifics
|
||||
|
||||
#define MICROPY_MPHALPORT_H "esp_mphal.h"
|
||||
#define MICROPY_HW_BOARD_NAME "ESP module"
|
||||
#define MICROPY_HW_MCU_NAME "ESP8266"
|
||||
#define MICROPY_PY_SYS_PLATFORM "esp8266"
|
||||
|
||||
#define MP_FASTCODE(n) __attribute__((section(".iram0.text." #n))) n
|
||||
|
||||
#define _assert(expr) ((expr) ? (void)0 : __assert_func(__FILE__, __LINE__, __func__, #expr))
|
@ -1,37 +0,0 @@
|
||||
#include <mpconfigport.h>
|
||||
|
||||
#undef MICROPY_EMIT_XTENSA
|
||||
#define MICROPY_EMIT_XTENSA (0)
|
||||
#undef MICROPY_EMIT_INLINE_XTENSA
|
||||
#define MICROPY_EMIT_INLINE_XTENSA (0)
|
||||
|
||||
#undef MICROPY_DEBUG_PRINTERS
|
||||
#define MICROPY_DEBUG_PRINTERS (0)
|
||||
|
||||
#undef MICROPY_ERROR_REPORTING
|
||||
#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_TERSE)
|
||||
|
||||
#undef MICROPY_VFS
|
||||
#define MICROPY_VFS (0)
|
||||
#undef MICROPY_VFS_FAT
|
||||
#define MICROPY_VFS_FAT (0)
|
||||
|
||||
#undef MICROPY_PERSISTENT_CODE_LOAD
|
||||
#define MICROPY_PERSISTENT_CODE_LOAD (0)
|
||||
|
||||
#undef MICROPY_PY_IO_FILEIO
|
||||
#define MICROPY_PY_IO_FILEIO (0)
|
||||
|
||||
#undef MICROPY_PY_SYS_STDIO_BUFFER
|
||||
#define MICROPY_PY_SYS_STDIO_BUFFER (0)
|
||||
#undef MICROPY_PY_BUILTINS_SLICE_ATTRS
|
||||
#define MICROPY_PY_BUILTINS_SLICE_ATTRS (0)
|
||||
#undef MICROPY_PY_ALL_SPECIAL_METHODS
|
||||
#define MICROPY_PY_ALL_SPECIAL_METHODS (0)
|
||||
|
||||
#undef MICROPY_PY_FRAMEBUF
|
||||
#define MICROPY_PY_FRAMEBUF (0)
|
||||
|
||||
#undef mp_import_stat
|
||||
#undef mp_builtin_open
|
||||
#undef mp_builtin_open_obj
|
@ -1,73 +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 <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include "py/mphal.h"
|
||||
#include "py/gc.h"
|
||||
|
||||
// Functions for external libs like axTLS, BerkeleyDB, etc.
|
||||
|
||||
void *malloc(size_t size) {
|
||||
void *p = gc_alloc(size, false, false);
|
||||
if (p == NULL) {
|
||||
// POSIX requires ENOMEM to be set in case of error
|
||||
errno = ENOMEM;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
void free(void *ptr) {
|
||||
gc_free(ptr);
|
||||
}
|
||||
void *calloc(size_t nmemb, size_t size) {
|
||||
return malloc(nmemb * size);
|
||||
}
|
||||
void *realloc(void *ptr, size_t size) {
|
||||
void *p = gc_realloc(ptr, size, true);
|
||||
if (p == NULL) {
|
||||
// POSIX requires ENOMEM to be set in case of error
|
||||
errno = ENOMEM;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
#undef htonl
|
||||
#undef ntohl
|
||||
uint32_t ntohl(uint32_t netlong) {
|
||||
return MP_BE32TOH(netlong);
|
||||
}
|
||||
uint32_t htonl(uint32_t netlong) {
|
||||
return MP_HTOBE32(netlong);
|
||||
}
|
||||
|
||||
time_t time(time_t *t) {
|
||||
return mp_hal_ticks_ms() / 1000;
|
||||
}
|
||||
|
||||
time_t mktime(void *tm) {
|
||||
return 0;
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2014 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.
|
||||
*/
|
||||
|
||||
// qstrs specific to this port, only needed if they aren't auto-generated
|
||||
|
||||
// Entries for sys.path
|
||||
Q(/)
|
||||
Q(/lib)
|
@ -1,29 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
// assumes endptr != NULL
|
||||
// doesn't check for sign
|
||||
// doesn't check for base-prefix
|
||||
long long int strtoll(const char *nptr, char **endptr, int base) {
|
||||
long long val = 0;
|
||||
|
||||
for (; *nptr; nptr++) {
|
||||
int v = *nptr;
|
||||
if ('0' <= v && v <= '9') {
|
||||
v -= '0';
|
||||
} else if ('A' <= v && v <= 'Z') {
|
||||
v -= 'A' - 10;
|
||||
} else if ('a' <= v && v <= 'z') {
|
||||
v -= 'a' - 10;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
if (v >= base) {
|
||||
break;
|
||||
}
|
||||
val = val * base + v;
|
||||
}
|
||||
|
||||
*endptr = (char*)nptr;
|
||||
|
||||
return val;
|
||||
}
|
@ -1,296 +0,0 @@
|
||||
/******************************************************************************
|
||||
* Copyright 2013-2014 Espressif Systems (Wuxi)
|
||||
*
|
||||
* FileName: uart.c
|
||||
*
|
||||
* Description: Two UART mode configration and interrupt handler.
|
||||
* Check your hardware connection while use this mode.
|
||||
*
|
||||
* Modification history:
|
||||
* 2014/3/12, v1.0 create this file.
|
||||
*******************************************************************************/
|
||||
#include "ets_sys.h"
|
||||
#include "osapi.h"
|
||||
#include "uart.h"
|
||||
#include "osapi.h"
|
||||
#include "uart_register.h"
|
||||
#include "etshal.h"
|
||||
#include "c_types.h"
|
||||
#include "user_interface.h"
|
||||
#include "esp_mphal.h"
|
||||
|
||||
// seems that this is missing in the Espressif SDK
|
||||
#define FUNC_U0RXD 0
|
||||
|
||||
#define UART_REPL UART0
|
||||
|
||||
// UartDev is defined and initialized in rom code.
|
||||
extern UartDevice UartDev;
|
||||
|
||||
// the uart to which OS messages go; -1 to disable
|
||||
static int uart_os = UART_OS;
|
||||
|
||||
#if MICROPY_REPL_EVENT_DRIVEN
|
||||
static os_event_t uart_evt_queue[16];
|
||||
#endif
|
||||
|
||||
static void uart0_rx_intr_handler(void *para);
|
||||
|
||||
void soft_reset(void);
|
||||
void mp_keyboard_interrupt(void);
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : uart_config
|
||||
* Description : Internal used function
|
||||
* UART0 used for data TX/RX, RX buffer size is 0x100, interrupt enabled
|
||||
* UART1 just used for debug output
|
||||
* Parameters : uart_no, use UART0 or UART1 defined ahead
|
||||
* Returns : NONE
|
||||
*******************************************************************************/
|
||||
static void ICACHE_FLASH_ATTR uart_config(uint8 uart_no) {
|
||||
if (uart_no == UART1) {
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_GPIO2_U, FUNC_U1TXD_BK);
|
||||
} else {
|
||||
ETS_UART_INTR_ATTACH(uart0_rx_intr_handler, NULL);
|
||||
PIN_PULLUP_DIS(PERIPHS_IO_MUX_U0TXD_U);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0TXD_U, FUNC_U0TXD);
|
||||
PIN_FUNC_SELECT(PERIPHS_IO_MUX_U0RXD_U, FUNC_U0RXD);
|
||||
}
|
||||
|
||||
uart_div_modify(uart_no, UART_CLK_FREQ / (UartDev.baut_rate));
|
||||
|
||||
WRITE_PERI_REG(UART_CONF0(uart_no), UartDev.exist_parity
|
||||
| UartDev.parity
|
||||
| (UartDev.stop_bits << UART_STOP_BIT_NUM_S)
|
||||
| (UartDev.data_bits << UART_BIT_NUM_S));
|
||||
|
||||
// clear rx and tx fifo,not ready
|
||||
SET_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST);
|
||||
CLEAR_PERI_REG_MASK(UART_CONF0(uart_no), UART_RXFIFO_RST | UART_TXFIFO_RST);
|
||||
|
||||
if (uart_no == UART0) {
|
||||
// set rx fifo trigger
|
||||
WRITE_PERI_REG(UART_CONF1(uart_no),
|
||||
((0x10 & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S) |
|
||||
((0x10 & UART_RX_FLOW_THRHD) << UART_RX_FLOW_THRHD_S) |
|
||||
UART_RX_FLOW_EN |
|
||||
(0x02 & UART_RX_TOUT_THRHD) << UART_RX_TOUT_THRHD_S |
|
||||
UART_RX_TOUT_EN);
|
||||
SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_TOUT_INT_ENA |
|
||||
UART_FRM_ERR_INT_ENA);
|
||||
} else {
|
||||
WRITE_PERI_REG(UART_CONF1(uart_no),
|
||||
((UartDev.rcv_buff.TrigLvl & UART_RXFIFO_FULL_THRHD) << UART_RXFIFO_FULL_THRHD_S));
|
||||
}
|
||||
|
||||
// clear all interrupt
|
||||
WRITE_PERI_REG(UART_INT_CLR(uart_no), 0xffff);
|
||||
// enable rx_interrupt
|
||||
SET_PERI_REG_MASK(UART_INT_ENA(uart_no), UART_RXFIFO_FULL_INT_ENA);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : uart1_tx_one_char
|
||||
* Description : Internal used function
|
||||
* Use uart1 interface to transfer one char
|
||||
* Parameters : uint8 TxChar - character to tx
|
||||
* Returns : OK
|
||||
*******************************************************************************/
|
||||
void uart_tx_one_char(uint8 uart, uint8 TxChar) {
|
||||
while (true) {
|
||||
uint32 fifo_cnt = READ_PERI_REG(UART_STATUS(uart)) & (UART_TXFIFO_CNT<<UART_TXFIFO_CNT_S);
|
||||
if ((fifo_cnt >> UART_TXFIFO_CNT_S & UART_TXFIFO_CNT) < 126) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
WRITE_PERI_REG(UART_FIFO(uart), TxChar);
|
||||
}
|
||||
|
||||
void uart_flush(uint8 uart) {
|
||||
while (true) {
|
||||
uint32 fifo_cnt = READ_PERI_REG(UART_STATUS(uart)) & (UART_TXFIFO_CNT<<UART_TXFIFO_CNT_S);
|
||||
if ((fifo_cnt >> UART_TXFIFO_CNT_S & UART_TXFIFO_CNT) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : uart1_write_char
|
||||
* Description : Internal used function
|
||||
* Do some special deal while tx char is '\r' or '\n'
|
||||
* Parameters : char c - character to tx
|
||||
* Returns : NONE
|
||||
*******************************************************************************/
|
||||
static void ICACHE_FLASH_ATTR
|
||||
uart_os_write_char(char c) {
|
||||
if (uart_os == -1) {
|
||||
return;
|
||||
}
|
||||
if (c == '\n') {
|
||||
uart_tx_one_char(uart_os, '\r');
|
||||
uart_tx_one_char(uart_os, '\n');
|
||||
} else if (c == '\r') {
|
||||
} else {
|
||||
uart_tx_one_char(uart_os, c);
|
||||
}
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR
|
||||
uart_os_config(int uart) {
|
||||
uart_os = uart;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : uart0_rx_intr_handler
|
||||
* Description : Internal used function
|
||||
* UART0 interrupt handler, add self handle code inside
|
||||
* Parameters : void *para - point to ETS_UART_INTR_ATTACH's arg
|
||||
* Returns : NONE
|
||||
*******************************************************************************/
|
||||
|
||||
static void uart0_rx_intr_handler(void *para) {
|
||||
/* uart0 and uart1 intr combine togther, when interrupt occur, see reg 0x3ff20020, bit2, bit0 represents
|
||||
* uart1 and uart0 respectively
|
||||
*/
|
||||
|
||||
uint8 uart_no = UART_REPL;
|
||||
|
||||
if (UART_FRM_ERR_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_FRM_ERR_INT_ST)) {
|
||||
// frame error
|
||||
WRITE_PERI_REG(UART_INT_CLR(uart_no), UART_FRM_ERR_INT_CLR);
|
||||
}
|
||||
|
||||
if (UART_RXFIFO_FULL_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_FULL_INT_ST)) {
|
||||
// fifo full
|
||||
goto read_chars;
|
||||
} else if (UART_RXFIFO_TOUT_INT_ST == (READ_PERI_REG(UART_INT_ST(uart_no)) & UART_RXFIFO_TOUT_INT_ST)) {
|
||||
read_chars:
|
||||
ETS_UART_INTR_DISABLE();
|
||||
|
||||
while (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S)) {
|
||||
uint8 RcvChar = READ_PERI_REG(UART_FIFO(uart_no)) & 0xff;
|
||||
if (RcvChar == mp_interrupt_char) {
|
||||
mp_keyboard_interrupt();
|
||||
} else {
|
||||
ringbuf_put(&stdin_ringbuf, RcvChar);
|
||||
}
|
||||
}
|
||||
|
||||
mp_hal_signal_input();
|
||||
|
||||
// Clear pending FIFO interrupts
|
||||
WRITE_PERI_REG(UART_INT_CLR(UART_REPL), UART_RXFIFO_TOUT_INT_CLR | UART_RXFIFO_FULL_INT_ST);
|
||||
ETS_UART_INTR_ENABLE();
|
||||
}
|
||||
}
|
||||
|
||||
// Waits at most timeout microseconds for at least 1 char to become ready for reading.
|
||||
// Returns true if something available, false if not.
|
||||
bool uart_rx_wait(uint32_t timeout_us) {
|
||||
uint32_t start = system_get_time();
|
||||
for (;;) {
|
||||
if (stdin_ringbuf.iget != stdin_ringbuf.iput) {
|
||||
return true; // have at least 1 char ready for reading
|
||||
}
|
||||
if (system_get_time() - start >= timeout_us) {
|
||||
return false; // timeout
|
||||
}
|
||||
ets_event_poll();
|
||||
}
|
||||
}
|
||||
|
||||
int uart_rx_any(uint8 uart) {
|
||||
if (stdin_ringbuf.iget != stdin_ringbuf.iput) {
|
||||
return true; // have at least 1 char ready for reading
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int uart_tx_any_room(uint8 uart) {
|
||||
uint32_t fifo_cnt = READ_PERI_REG(UART_STATUS(uart)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S);
|
||||
if ((fifo_cnt >> UART_TXFIFO_CNT_S & UART_TXFIFO_CNT) >= 126) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// Returns char from the input buffer, else -1 if buffer is empty.
|
||||
int uart_rx_char(void) {
|
||||
return ringbuf_get(&stdin_ringbuf);
|
||||
}
|
||||
|
||||
int uart_rx_one_char(uint8 uart_no) {
|
||||
if (READ_PERI_REG(UART_STATUS(uart_no)) & (UART_RXFIFO_CNT << UART_RXFIFO_CNT_S)) {
|
||||
return READ_PERI_REG(UART_FIFO(uart_no)) & 0xff;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* FunctionName : uart_init
|
||||
* Description : user interface for init uart
|
||||
* Parameters : UartBautRate uart0_br - uart0 bautrate
|
||||
* UartBautRate uart1_br - uart1 bautrate
|
||||
* Returns : NONE
|
||||
*******************************************************************************/
|
||||
void ICACHE_FLASH_ATTR uart_init(UartBautRate uart0_br, UartBautRate uart1_br) {
|
||||
// rom use 74880 baut_rate, here reinitialize
|
||||
UartDev.baut_rate = uart0_br;
|
||||
uart_config(UART0);
|
||||
UartDev.baut_rate = uart1_br;
|
||||
uart_config(UART1);
|
||||
ETS_UART_INTR_ENABLE();
|
||||
|
||||
// install handler for "os" messages
|
||||
os_install_putc1((void *)uart_os_write_char);
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR uart_reattach() {
|
||||
uart_init(UART_BIT_RATE_74880, UART_BIT_RATE_74880);
|
||||
}
|
||||
|
||||
void ICACHE_FLASH_ATTR uart_setup(uint8 uart) {
|
||||
ETS_UART_INTR_DISABLE();
|
||||
uart_config(uart);
|
||||
ETS_UART_INTR_ENABLE();
|
||||
}
|
||||
|
||||
// Task-based UART interface
|
||||
|
||||
#include "py/obj.h"
|
||||
#include "lib/utils/pyexec.h"
|
||||
|
||||
#if MICROPY_REPL_EVENT_DRIVEN
|
||||
void uart_task_handler(os_event_t *evt) {
|
||||
if (pyexec_repl_active) {
|
||||
// TODO: Just returning here isn't exactly right.
|
||||
// What really should be done is something like
|
||||
// enquing delayed event to itself, for another
|
||||
// chance to feed data to REPL. Otherwise, there
|
||||
// can be situation when buffer has bunch of data,
|
||||
// and sits unprocessed, because we consumed all
|
||||
// processing signals like this.
|
||||
return;
|
||||
}
|
||||
|
||||
int c, ret = 0;
|
||||
while ((c = ringbuf_get(&stdin_ringbuf)) >= 0) {
|
||||
if (c == mp_interrupt_char) {
|
||||
mp_keyboard_interrupt();
|
||||
}
|
||||
ret = pyexec_event_repl_process_char(c);
|
||||
if (ret & PYEXEC_FORCED_EXIT) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret & PYEXEC_FORCED_EXIT) {
|
||||
soft_reset();
|
||||
}
|
||||
}
|
||||
|
||||
void uart_task_init() {
|
||||
system_os_task(uart_task_handler, UART_TASK_ID, uart_evt_queue, sizeof(uart_evt_queue) / sizeof(*uart_evt_queue));
|
||||
}
|
||||
#endif
|
@ -1,106 +0,0 @@
|
||||
#ifndef MICROPY_INCLUDED_ESP8266_UART_H
|
||||
#define MICROPY_INCLUDED_ESP8266_UART_H
|
||||
|
||||
#include <eagle_soc.h>
|
||||
|
||||
#define UART0 (0)
|
||||
#define UART1 (1)
|
||||
|
||||
typedef enum {
|
||||
UART_FIVE_BITS = 0x0,
|
||||
UART_SIX_BITS = 0x1,
|
||||
UART_SEVEN_BITS = 0x2,
|
||||
UART_EIGHT_BITS = 0x3
|
||||
} UartBitsNum4Char;
|
||||
|
||||
typedef enum {
|
||||
UART_ONE_STOP_BIT = 0x1,
|
||||
UART_ONE_HALF_STOP_BIT = 0x2,
|
||||
UART_TWO_STOP_BIT = 0x3
|
||||
} UartStopBitsNum;
|
||||
|
||||
typedef enum {
|
||||
UART_NONE_BITS = 0,
|
||||
UART_ODD_BITS = BIT0,
|
||||
UART_EVEN_BITS = 0
|
||||
} UartParityMode;
|
||||
|
||||
typedef enum {
|
||||
UART_STICK_PARITY_DIS = 0,
|
||||
UART_STICK_PARITY_EN = BIT1
|
||||
} UartExistParity;
|
||||
|
||||
typedef enum {
|
||||
UART_BIT_RATE_9600 = 9600,
|
||||
UART_BIT_RATE_19200 = 19200,
|
||||
UART_BIT_RATE_38400 = 38400,
|
||||
UART_BIT_RATE_57600 = 57600,
|
||||
UART_BIT_RATE_74880 = 74880,
|
||||
UART_BIT_RATE_115200 = 115200,
|
||||
UART_BIT_RATE_230400 = 230400,
|
||||
UART_BIT_RATE_256000 = 256000,
|
||||
UART_BIT_RATE_460800 = 460800,
|
||||
UART_BIT_RATE_921600 = 921600
|
||||
} UartBautRate;
|
||||
|
||||
typedef enum {
|
||||
UART_NONE_CTRL,
|
||||
UART_HARDWARE_CTRL,
|
||||
UART_XON_XOFF_CTRL
|
||||
} UartFlowCtrl;
|
||||
|
||||
typedef enum {
|
||||
UART_EMPTY,
|
||||
UART_UNDER_WRITE,
|
||||
UART_WRITE_OVER
|
||||
} RcvMsgBuffState;
|
||||
|
||||
typedef struct {
|
||||
uint32 RcvBuffSize;
|
||||
uint8 *pRcvMsgBuff;
|
||||
uint8 *pWritePos;
|
||||
uint8 *pReadPos;
|
||||
uint8 TrigLvl; //JLU: may need to pad
|
||||
RcvMsgBuffState BuffState;
|
||||
} RcvMsgBuff;
|
||||
|
||||
typedef struct {
|
||||
uint32 TrxBuffSize;
|
||||
uint8 *pTrxBuff;
|
||||
} TrxMsgBuff;
|
||||
|
||||
typedef enum {
|
||||
UART_BAUD_RATE_DET,
|
||||
UART_WAIT_SYNC_FRM,
|
||||
UART_SRCH_MSG_HEAD,
|
||||
UART_RCV_MSG_BODY,
|
||||
UART_RCV_ESC_CHAR,
|
||||
} RcvMsgState;
|
||||
|
||||
typedef struct {
|
||||
UartBautRate baut_rate;
|
||||
UartBitsNum4Char data_bits;
|
||||
UartExistParity exist_parity;
|
||||
UartParityMode parity; // chip size in byte
|
||||
UartStopBitsNum stop_bits;
|
||||
UartFlowCtrl flow_ctrl;
|
||||
RcvMsgBuff rcv_buff;
|
||||
TrxMsgBuff trx_buff;
|
||||
RcvMsgState rcv_state;
|
||||
int received;
|
||||
int buff_uart_no; //indicate which uart use tx/rx buffer
|
||||
} UartDevice;
|
||||
|
||||
void uart_init(UartBautRate uart0_br, UartBautRate uart1_br);
|
||||
int uart0_rx(void);
|
||||
bool uart_rx_wait(uint32_t timeout_us);
|
||||
int uart_rx_char(void);
|
||||
void uart_tx_one_char(uint8 uart, uint8 TxChar);
|
||||
void uart_flush(uint8 uart);
|
||||
void uart_os_config(int uart);
|
||||
void uart_setup(uint8 uart);
|
||||
// check status of rx/tx
|
||||
int uart_rx_any(uint8 uart);
|
||||
int uart_tx_any_room(uint8 uart);
|
||||
|
||||
#endif // MICROPY_INCLUDED_ESP8266_UART_H
|
@ -1,128 +0,0 @@
|
||||
//Generated at 2012-07-03 18:44:06
|
||||
/*
|
||||
* Copyright (c) 2010 - 2011 Espressif System
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef UART_REGISTER_H_INCLUDED
|
||||
#define UART_REGISTER_H_INCLUDED
|
||||
#define REG_UART_BASE( i ) (0x60000000+(i)*0xf00)
|
||||
//version value:32'h062000
|
||||
|
||||
#define UART_FIFO( i ) (REG_UART_BASE( i ) + 0x0)
|
||||
#define UART_RXFIFO_RD_BYTE 0x000000FF
|
||||
#define UART_RXFIFO_RD_BYTE_S 0
|
||||
|
||||
#define UART_INT_RAW( i ) (REG_UART_BASE( i ) + 0x4)
|
||||
#define UART_RXFIFO_TOUT_INT_RAW (BIT(8))
|
||||
#define UART_BRK_DET_INT_RAW (BIT(7))
|
||||
#define UART_CTS_CHG_INT_RAW (BIT(6))
|
||||
#define UART_DSR_CHG_INT_RAW (BIT(5))
|
||||
#define UART_RXFIFO_OVF_INT_RAW (BIT(4))
|
||||
#define UART_FRM_ERR_INT_RAW (BIT(3))
|
||||
#define UART_PARITY_ERR_INT_RAW (BIT(2))
|
||||
#define UART_TXFIFO_EMPTY_INT_RAW (BIT(1))
|
||||
#define UART_RXFIFO_FULL_INT_RAW (BIT(0))
|
||||
|
||||
#define UART_INT_ST( i ) (REG_UART_BASE( i ) + 0x8)
|
||||
#define UART_RXFIFO_TOUT_INT_ST (BIT(8))
|
||||
#define UART_BRK_DET_INT_ST (BIT(7))
|
||||
#define UART_CTS_CHG_INT_ST (BIT(6))
|
||||
#define UART_DSR_CHG_INT_ST (BIT(5))
|
||||
#define UART_RXFIFO_OVF_INT_ST (BIT(4))
|
||||
#define UART_FRM_ERR_INT_ST (BIT(3))
|
||||
#define UART_PARITY_ERR_INT_ST (BIT(2))
|
||||
#define UART_TXFIFO_EMPTY_INT_ST (BIT(1))
|
||||
#define UART_RXFIFO_FULL_INT_ST (BIT(0))
|
||||
|
||||
#define UART_INT_ENA( i ) (REG_UART_BASE( i ) + 0xC)
|
||||
#define UART_RXFIFO_TOUT_INT_ENA (BIT(8))
|
||||
#define UART_BRK_DET_INT_ENA (BIT(7))
|
||||
#define UART_CTS_CHG_INT_ENA (BIT(6))
|
||||
#define UART_DSR_CHG_INT_ENA (BIT(5))
|
||||
#define UART_RXFIFO_OVF_INT_ENA (BIT(4))
|
||||
#define UART_FRM_ERR_INT_ENA (BIT(3))
|
||||
#define UART_PARITY_ERR_INT_ENA (BIT(2))
|
||||
#define UART_TXFIFO_EMPTY_INT_ENA (BIT(1))
|
||||
#define UART_RXFIFO_FULL_INT_ENA (BIT(0))
|
||||
|
||||
#define UART_INT_CLR( i ) (REG_UART_BASE( i ) + 0x10)
|
||||
#define UART_RXFIFO_TOUT_INT_CLR (BIT(8))
|
||||
#define UART_BRK_DET_INT_CLR (BIT(7))
|
||||
#define UART_CTS_CHG_INT_CLR (BIT(6))
|
||||
#define UART_DSR_CHG_INT_CLR (BIT(5))
|
||||
#define UART_RXFIFO_OVF_INT_CLR (BIT(4))
|
||||
#define UART_FRM_ERR_INT_CLR (BIT(3))
|
||||
#define UART_PARITY_ERR_INT_CLR (BIT(2))
|
||||
#define UART_TXFIFO_EMPTY_INT_CLR (BIT(1))
|
||||
#define UART_RXFIFO_FULL_INT_CLR (BIT(0))
|
||||
|
||||
#define UART_CLKDIV( i ) (REG_UART_BASE( i ) + 0x14)
|
||||
#define UART_CLKDIV_CNT 0x000FFFFF
|
||||
#define UART_CLKDIV_S 0
|
||||
|
||||
#define UART_AUTOBAUD( i ) (REG_UART_BASE( i ) + 0x18)
|
||||
#define UART_GLITCH_FILT 0x000000FF
|
||||
#define UART_GLITCH_FILT_S 8
|
||||
#define UART_AUTOBAUD_EN (BIT(0))
|
||||
|
||||
#define UART_STATUS( i ) (REG_UART_BASE( i ) + 0x1C)
|
||||
#define UART_TXD (BIT(31))
|
||||
#define UART_RTSN (BIT(30))
|
||||
#define UART_DTRN (BIT(29))
|
||||
#define UART_TXFIFO_CNT 0x000000FF
|
||||
#define UART_TXFIFO_CNT_S 16
|
||||
#define UART_RXD (BIT(15))
|
||||
#define UART_CTSN (BIT(14))
|
||||
#define UART_DSRN (BIT(13))
|
||||
#define UART_RXFIFO_CNT 0x000000FF
|
||||
#define UART_RXFIFO_CNT_S 0
|
||||
|
||||
#define UART_CONF0( i ) (REG_UART_BASE( i ) + 0x20)
|
||||
#define UART_TXFIFO_RST (BIT(18))
|
||||
#define UART_RXFIFO_RST (BIT(17))
|
||||
#define UART_IRDA_EN (BIT(16))
|
||||
#define UART_TX_FLOW_EN (BIT(15))
|
||||
#define UART_LOOPBACK (BIT(14))
|
||||
#define UART_IRDA_RX_INV (BIT(13))
|
||||
#define UART_IRDA_TX_INV (BIT(12))
|
||||
#define UART_IRDA_WCTL (BIT(11))
|
||||
#define UART_IRDA_TX_EN (BIT(10))
|
||||
#define UART_IRDA_DPLX (BIT(9))
|
||||
#define UART_TXD_BRK (BIT(8))
|
||||
#define UART_SW_DTR (BIT(7))
|
||||
#define UART_SW_RTS (BIT(6))
|
||||
#define UART_STOP_BIT_NUM 0x00000003
|
||||
#define UART_STOP_BIT_NUM_S 4
|
||||
#define UART_BIT_NUM 0x00000003
|
||||
#define UART_BIT_NUM_S 2
|
||||
#define UART_PARITY_EN (BIT(1))
|
||||
#define UART_PARITY (BIT(0))
|
||||
|
||||
#define UART_CONF1( i ) (REG_UART_BASE( i ) + 0x24)
|
||||
#define UART_RX_TOUT_EN (BIT(31))
|
||||
#define UART_RX_TOUT_THRHD 0x0000007F
|
||||
#define UART_RX_TOUT_THRHD_S 24
|
||||
#define UART_RX_FLOW_EN (BIT(23))
|
||||
#define UART_RX_FLOW_THRHD 0x0000007F
|
||||
#define UART_RX_FLOW_THRHD_S 16
|
||||
#define UART_TXFIFO_EMPTY_THRHD 0x0000007F
|
||||
#define UART_TXFIFO_EMPTY_THRHD_S 8
|
||||
#define UART_RXFIFO_FULL_THRHD 0x0000007F
|
||||
#define UART_RXFIFO_FULL_THRHD_S 0
|
||||
|
||||
#define UART_LOWPULSE( i ) (REG_UART_BASE( i ) + 0x28)
|
||||
#define UART_LOWPULSE_MIN_CNT 0x000FFFFF
|
||||
#define UART_LOWPULSE_MIN_CNT_S 0
|
||||
|
||||
#define UART_HIGHPULSE( i ) (REG_UART_BASE( i ) + 0x2C)
|
||||
#define UART_HIGHPULSE_MIN_CNT 0x000FFFFF
|
||||
#define UART_HIGHPULSE_MIN_CNT_S 0
|
||||
|
||||
#define UART_PULSE_NUM( i ) (REG_UART_BASE( i ) + 0x30)
|
||||
#define UART_PULSE_NUM_CNT 0x0003FF
|
||||
#define UART_PULSE_NUM_CNT_S 0
|
||||
|
||||
#define UART_DATE( i ) (REG_UART_BASE( i ) + 0x78)
|
||||
#define UART_ID( i ) (REG_UART_BASE( i ) + 0x7C)
|
||||
#endif // UART_REGISTER_H_INCLUDED
|
@ -1 +0,0 @@
|
||||
// empty
|
@ -1,59 +0,0 @@
|
||||
/*
|
||||
* This file is part of the MicroPython project, http://micropython.org/
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* Copyright (c) 2016 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_ESP8266_XTIRQ_H
|
||||
#define MICROPY_INCLUDED_ESP8266_XTIRQ_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
// returns the value of "intlevel" from the PS register
|
||||
static inline uint32_t query_irq(void) {
|
||||
uint32_t ps;
|
||||
__asm__ volatile("rsr %0, ps" : "=a" (ps));
|
||||
return ps & 0xf;
|
||||
}
|
||||
|
||||
// irqs with a priority value lower or equal to "intlevel" will be disabled
|
||||
// "intlevel" should be between 0 and 15 inclusive, and should be an integer
|
||||
static inline uint32_t raise_irq_pri(uint32_t intlevel) {
|
||||
uint32_t old_ps;
|
||||
__asm__ volatile ("rsil %0, %1" : "=a" (old_ps) : "I" (intlevel));
|
||||
return old_ps;
|
||||
}
|
||||
|
||||
// "ps" should be the value returned from raise_irq_pri
|
||||
static inline void restore_irq_pri(uint32_t ps) {
|
||||
__asm__ volatile ("wsr %0, ps; rsync" :: "a" (ps));
|
||||
}
|
||||
|
||||
static inline uint32_t disable_irq(void) {
|
||||
return raise_irq_pri(15);
|
||||
}
|
||||
|
||||
static inline void enable_irq(uint32_t irq_state) {
|
||||
restore_irq_pri(irq_state);
|
||||
}
|
||||
|
||||
#endif // MICROPY_INCLUDED_ESP8266_XTIRQ_H
|
Loading…
x
Reference in New Issue
Block a user