mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch master into feature/logging
* branch master: (51 commits) fix typos callback: add a void* pointer with each callback header: callbacks use "void *" as arguments header: format and fix typos add wifi api comments add wifi api comments components/spi_flash: call SPIUnlock only once components/spi_flash: improve comments and readability esp32 cpu_start: Include rom/uart.h, remove inline ROM function declarations bootloader: Add bootloader Kconfig Fix bug where nesting vTaskEnterCritical calls would not re-enable interrupts after vTaskExitCritical sections. installed gitlab key in global before_script, don't need to overwrite in template before_script ci: Use github repo for wifi libraries on master branch, gitlab repo otherwise components/esp32,spi_flash: update some comments components/esp32: remove dependency of WIFI_ENABLED on FREERTOS_UNICORE esp32/lib: Bump WiFi revision update ci: build ssc with idf submodule wifi lib components/esp32: add inter-processor call API and implement spi_flash through it add MACRO to get flash pad number from efuse value add comments to register read/write operations ...
This commit is contained in:
commit
2fc60ba938
@ -4,11 +4,25 @@ stages:
|
||||
- deploy
|
||||
|
||||
before_script:
|
||||
# add gitlab ssh key
|
||||
- mkdir -p ~/.ssh
|
||||
- chmod 700 ~/.ssh
|
||||
- echo -n $GITLAB_KEY >> ~/.ssh/id_rsa_base64
|
||||
- base64 --decode --ignore-garbage ~/.ssh/id_rsa_base64 > ~/.ssh/id_rsa
|
||||
- chmod 600 ~/.ssh/id_rsa
|
||||
- echo -e "Host gitlab.espressif.cn\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
|
||||
|
||||
# if testing master branch, use github wifi libs.
|
||||
# if testing other branches, use gitlab wifi libs (as maybe changes aren't merged to master yet)
|
||||
- test "${CI_BUILD_REF_NAME}" = "master" || sed -i "s%https://github.com/espressif/esp32-wifi-lib%ssh://git@gitlab.espressif.cn:27227/idf/esp32-wifi-lib%" .gitmodules
|
||||
# fetch all submodules
|
||||
- git submodule update --init --recursive
|
||||
|
||||
build_template_app:
|
||||
stage: build
|
||||
image: espressif/esp32-ci-env
|
||||
tags:
|
||||
- build
|
||||
|
||||
variables:
|
||||
SDK_PATH: "$CI_PROJECT_DIR"
|
||||
@ -18,12 +32,47 @@ build_template_app:
|
||||
script:
|
||||
- git clone https://github.com/espressif/esp-idf-template.git
|
||||
- cd esp-idf-template
|
||||
# Try to use the same branch name for esp-idf-template that we're
|
||||
# using on esp-idf. If it doesn't exist then just stick to the default
|
||||
# branch
|
||||
- git checkout ${CI_BUILD_REF_NAME} || echo "Using esp-idf-template default branch..."
|
||||
- make defconfig
|
||||
- make all
|
||||
|
||||
|
||||
.build_gitlab: &build_template
|
||||
stage: build
|
||||
tags:
|
||||
- build
|
||||
image: espressif/esp32-ci-env
|
||||
|
||||
variables:
|
||||
SDK_PATH: "$CI_PROJECT_DIR"
|
||||
IDF_PATH: "$CI_PROJECT_DIR"
|
||||
GIT_STRATEGY: clone
|
||||
|
||||
build_ssc:
|
||||
<<: *build_template
|
||||
artifacts:
|
||||
paths:
|
||||
- ./SSC/build/*.bin
|
||||
- ./SSC/build/*.elf
|
||||
- ./SSC/build/*.map
|
||||
- ./SSC/build/bootloader/*.bin
|
||||
expire_in: 6 mos
|
||||
|
||||
script:
|
||||
- git clone ssh://git@gitlab.espressif.cn:27227/yinling/SSC.git
|
||||
- cd SSC
|
||||
- make defconfig
|
||||
- chmod +x gen_misc_ng.sh
|
||||
- ./gen_misc_ng.sh
|
||||
|
||||
test_nvs_on_host:
|
||||
stage: test
|
||||
image: espressif/esp32-ci-env
|
||||
tags:
|
||||
- nvs_host_test
|
||||
script:
|
||||
- cd components/nvs_flash/test
|
||||
- make test
|
||||
@ -31,15 +80,58 @@ test_nvs_on_host:
|
||||
test_build_system:
|
||||
stage: test
|
||||
image: espressif/esp32-ci-env
|
||||
tags:
|
||||
- build_test
|
||||
variables:
|
||||
IDF_PATH: "$CI_PROJECT_DIR"
|
||||
script:
|
||||
- ./make/test_build_system.sh
|
||||
|
||||
|
||||
|
||||
# template for test jobs
|
||||
.test_template: &test_template
|
||||
stage: test
|
||||
when: on_success
|
||||
only:
|
||||
- master
|
||||
|
||||
variables:
|
||||
# need user to set SDK_NAME and CONFIG_FILE (may need to set BIN_PATH and APP_NAME later) in before_script
|
||||
SCRIPT_PATH: /home/gitlab-runner/auto_test_script
|
||||
BIN_PATH: ${CI_PROJECT_DIR}/SSC/build/
|
||||
APP_NAME: ssc
|
||||
LOG_PATH: $CI_PROJECT_DIR/$CI_BUILD_REF
|
||||
|
||||
artifacts:
|
||||
when: always
|
||||
paths:
|
||||
- $LOG_PATH
|
||||
expire_in: 6 mos
|
||||
|
||||
script:
|
||||
- cd $SCRIPT_PATH
|
||||
- python CIRunner.py -l $LOG_PATH -c $SDK_NAME/$CONFIG_FILE bin_path $APP_NAME $BIN_PATH
|
||||
|
||||
sanity_test:
|
||||
<<: *test_template
|
||||
tags:
|
||||
- ESP32
|
||||
- SSC_T1_1
|
||||
- SSC_T2_1
|
||||
- SSC_T1_WAN
|
||||
before_script:
|
||||
- SDK_NAME=ESP32_IDF
|
||||
- CONFIG_FILE=sanity_test.yml
|
||||
|
||||
|
||||
|
||||
push_master_to_github:
|
||||
stage: deploy
|
||||
only:
|
||||
- master
|
||||
tags:
|
||||
- deploy
|
||||
when: on_success
|
||||
image: espressif/esp32-ci-env
|
||||
variables:
|
||||
|
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -1,3 +1,6 @@
|
||||
[submodule "components/esp32/lib"]
|
||||
path = components/esp32/lib
|
||||
url = https://github.com/espressif/esp32-wifi-lib.git
|
||||
[submodule "components/esptool_py/esptool"]
|
||||
path = components/esptool_py/esptool
|
||||
url = https://github.com/themadinventor/esptool.git
|
||||
|
265
README.buildenv
265
README.buildenv
@ -1,265 +0,0 @@
|
||||
The build structure of the Espressif IoT Development Framework explained.
|
||||
|
||||
An ESP-IDF project can be seen as an almagation of a number of components.
|
||||
For example, for a webserver that shows the current humidity, we would
|
||||
have:
|
||||
- The ESP32 base libraries (libc, rom bindings etc)
|
||||
- The WiFi drivers
|
||||
- A TCP/IP stack
|
||||
- The FreeRTOS operating system
|
||||
- A webserver
|
||||
- A driver for an humidity sensor
|
||||
- Main code tying it all together
|
||||
|
||||
ESP-IDF makes these components explicit and configurable. To do that, when a project
|
||||
is compiled, the build environment will look up all the components in the
|
||||
ESP-IDF directories, the project directories and optionally custom other component
|
||||
directories. It then allows the user to configure compile-time options using
|
||||
a friendly text-based menu system to customize the ESP-IDF as well as other components
|
||||
to the requirements of the project. After the components are customized, the
|
||||
build process will compile everything into an output file, which can then be uploaded
|
||||
into a board in a way that can also be defined by components.
|
||||
|
||||
A project in this sense is defined as a directory under which all the files required
|
||||
to build it live, excluding the ESP-IDF files and the toolchain. A simple project
|
||||
tree looks like this:
|
||||
|
||||
- myProject/ - build/
|
||||
- components/ - component1/ - Makefile
|
||||
- Kconfig
|
||||
- src1.c
|
||||
- component2/ - Makefile
|
||||
- Kconfig
|
||||
- src1.c
|
||||
- main/ - src1.c
|
||||
- src2.c
|
||||
- Makefile
|
||||
|
||||
|
||||
As we can see, a project consists of a components/ subdirectory containing its
|
||||
components as well as one or more directories containing the project-specific
|
||||
sources; by default a single directory called 'main' is assumed. The project
|
||||
directory will also have a Makefile where the projects name as well as optionally
|
||||
other options are defined. After compilation, the project directory will contain
|
||||
a 'build'-directory containing all of the objects, libraries and other generated
|
||||
files as well as the final binary.
|
||||
|
||||
Components also have a Makefile containing various definititions influencing
|
||||
the build process of the component as well as the project it's used in, as
|
||||
well as a Kconfig file defining the compile-time options that are settable
|
||||
by means of the menu system.
|
||||
|
||||
|
||||
Project makefile variables that can be set by the programmer:
|
||||
PROJECT_NAME: Mandatory. Name for the project
|
||||
BUILD_DIR_BASE: Set the directory where all objects/libraries/binaries end up in.
|
||||
Defaults to $(PROJECT_PATH)/build
|
||||
COMPONENT_DIRS: Search path for components. Defaults to the component/ directories
|
||||
in the ESP-IDF path and the project path.
|
||||
COMPONENTS: A list of component names. Defaults to all the component found in the
|
||||
COMPONENT_DIRS directory
|
||||
EXTRA_COMPONENT_DIRS: Defaults to unset. Use this to add directories to the default
|
||||
COMPONENT_DIRS.
|
||||
SRCDIRS: Directories under the project dir containing project-specific sources.
|
||||
Defaults to 'main'. These are treated as 'lite' components: they do not have
|
||||
include directories that are passed to the compilation pass of all components and
|
||||
they do not have a Kconfig option.
|
||||
|
||||
|
||||
Component makefile variables that can be set by the programmer:
|
||||
COMPONENT_ADD_INCLUDEDIRS: Relative path to include directories to be added to
|
||||
the entire project
|
||||
COMPONENT_PRIV_INCLUDEDIRS: Relative path to include directories that are only used
|
||||
when compiling this specific component
|
||||
COMPONENT_DEPENDS: Names of any components that need to be compiled before this component.
|
||||
COMPONENT_ADD_LDFLAGS: Ld flags to add for this project. Defaults to -l$(COMPONENT_NAME).
|
||||
Add libraries etc in the current directory as $(abspath libwhatever.a)
|
||||
COMPONENT_EXTRA_INCLUDES: Any extra include paths. These will be prefixed with '-I' and
|
||||
passed to the compiler; please put absolute paths here.
|
||||
COMPONENT_SRCDIRS: Relative directories to look in for sources. Defaults to '.', the current
|
||||
directory (the root of the component) only. Use this to specify any subdirectories. Note
|
||||
that specifying this overwrites the default action of compiling everything in the
|
||||
components root dir; to keep this behaviour please also add '.' as a directory in this
|
||||
list.
|
||||
COMPONENT_OBJS: Object files to compile. Defaults to the .o variants of all .c and .S files
|
||||
that are found in COMPONENT_SRCDIRS.
|
||||
COMPONENT_EXTRA_CLEAN: Files that are generated using rules in the components Makefile
|
||||
that also need to be cleaned
|
||||
COMPONENT_BUILDRECIPE: Recipe to build the component. Optional. Defaults to building all
|
||||
COMPONENT_OBJS and linking them into lib(componentname).a
|
||||
COMPONENT_CLEANRECIPE: Recipe to clean the component. Optional. Defaults to removing
|
||||
all built objects and libraries.
|
||||
COMPONENT_BUILD_DIR: Equals the cwd of the component build, which is the build dir
|
||||
of the component (where all the .o etc files should be created).
|
||||
|
||||
|
||||
These variables are already set early on in the Makefile and the values in it will
|
||||
be usable in component or project Makefiles:
|
||||
CC, LD, AR, OBJCOPY: Xtensa gcc tools
|
||||
HOSTCC, HOSTLD etc: Host gcc tools
|
||||
LDFLAGS, CFLAGS: Set to usable values as defined in ESP-IDF Makefile
|
||||
PROJECT_NAME: Name of the project, as set in project makefile
|
||||
PROJECT_PATH: Path to the root of the project folder
|
||||
COMPONENTS: Name of the components to be included
|
||||
CONFIG_*: Values set by 'make menuconfig' also have corresponding Makefile variables.
|
||||
|
||||
For components, there also are these defines:
|
||||
COMPONENT_PATH: Absolute path to the root of the source tree of the component we're
|
||||
compiling
|
||||
COMPONENT_LIBRARY: The full path to the static library the components compilation pass
|
||||
is supposed to generate
|
||||
|
||||
|
||||
How this works:
|
||||
The Make process is always invoked from the project directory by the
|
||||
user; invoking it anywhere else gives an error. This is what happens if
|
||||
we build a binary:
|
||||
|
||||
The Makefile first determines how it was included. It determines it was
|
||||
included as a project file in this case and will continue to figure out
|
||||
various paths as well as the components available to it. It will also
|
||||
collect the ldflags and includes that the components specify they need.
|
||||
It does this by running a dummy Make on the components with a target that
|
||||
will output these values.
|
||||
|
||||
The Makefile will then create targets to build the lib*.a libraries of
|
||||
all components and make the elf target depend on this. The targets
|
||||
invoke Make on the makefiles of the components in a subshell: this way
|
||||
the components have full freedom to do whatever is necessary to build
|
||||
the library without influencing other components. By default, the
|
||||
component includes the utility makefile $(IDF_PATH)/make/component.mk.
|
||||
This provides default targets and configurations that will work
|
||||
out-of-the-box for most projects.
|
||||
|
||||
For components that have parts that need to be run when building of the
|
||||
project is done, you can create a file called Makefile.projbuild in the
|
||||
component root directory. This file will be included in the main
|
||||
Makefile. For the menu, there's an equivalent: if you want to include
|
||||
options not in the 'components' submenu, create a Kconfig.projbuild and
|
||||
it will be included in the main menu of menuconfig. Take good care when
|
||||
(re)defining stuff here: because it's included with all the other
|
||||
.projbuild files, it's possible to overwrite variables or re-declare
|
||||
targets defined in the ESP-IDF makefile/Kconfig and other .projbuild files
|
||||
|
||||
|
||||
WRITING COMPONENT MAKEFILES
|
||||
|
||||
A component consists of a directory which doubles as the name for the
|
||||
component: a component named 'httpd' lives in a directory called 'httpd'
|
||||
Because components usually live under the project directory (although
|
||||
they can also reside in an other folder), the path to this may be
|
||||
something like /home/myuser/projects/myprojects/components/httpd .
|
||||
|
||||
One of the things that most components will have is a Makefile,
|
||||
containing instructions on how to build the component. Because the
|
||||
build environment tries to set reasonable defaults that will work most
|
||||
of the time, a component Makefile can be pretty small. At the absolute
|
||||
minimum, it will just include the ESP-IDF component makefile, which adds
|
||||
component functionality:
|
||||
|
||||
----8<----
|
||||
include $(IDF_PATH)/make/component.mk
|
||||
---->8----
|
||||
|
||||
This will take all the .c and .S files in the component root and compile
|
||||
them into object files, finally linking them into a library.
|
||||
Subdirectories are ignored; if your project has sources in subdirectories
|
||||
instead of in the root of the component, you can tell that to the build
|
||||
system by setting COMPONENT_SRCDIRS:
|
||||
|
||||
----8<----
|
||||
COMPONENT_SRCDIRS := src1 src2
|
||||
include $(IDF_PATH)/make/component.mk
|
||||
---->8----
|
||||
|
||||
This will compile all source files in the src1/ and src2/ subdirectories
|
||||
instead.
|
||||
|
||||
The standard component.mk logic adds all .S and .c files in the source
|
||||
directories as sources to be compiled unconditionally. It is possible
|
||||
to circumvent that logic and hardcode the objects to be compiled by
|
||||
manually setting the COMPONENT_OBJS variable to the name of the
|
||||
objects that need to be generated:
|
||||
|
||||
----8<----
|
||||
COMPONENT_OBJS := file1.o file2.o thing/filea.o thing/fileb.o anotherthing/main.o
|
||||
include $(IDF_PATH)/make/component.mk
|
||||
---->8----
|
||||
|
||||
This can also be used in order to conditionally compile some files
|
||||
dependent on the options selected in the Makefile:
|
||||
|
||||
Kconfig:
|
||||
----8<----
|
||||
config FOO_ENABLE_BAR
|
||||
bool "Enable the BAR feature."
|
||||
help
|
||||
This enables the BAR feature of the FOO component.
|
||||
---->8----
|
||||
|
||||
Makefile:
|
||||
----8<----
|
||||
COMPONENT_OBJS := foo_a.o foo_b.o $(if $(CONFIG_FOO_ENABLE_BAR),foo_bar.o foo_bar_interface.o)
|
||||
include $(IDF_PATH)/make/component.mk
|
||||
---->8----
|
||||
|
||||
Some components will have a situation where a source file isn't supplied
|
||||
with the component itself but has to be generated from another file. Say
|
||||
our component has a header file that consists of the converted binary
|
||||
data of a BMP file, converted using a hypothetical tool called bmp2h. The
|
||||
header file is then included in as C source file called graphics_lib.c.
|
||||
|
||||
----8<----
|
||||
COMPONENT_EXTRA_CLEAN := logo.h
|
||||
|
||||
graphics_lib.o: logo.h
|
||||
|
||||
logo.h: $(COMPONENT_PATH)/logo.bmp
|
||||
bmp2h -i $^ -o $@
|
||||
|
||||
include $(IDF_PATH)/make/component.mk
|
||||
---->8----
|
||||
|
||||
In this example, graphics_lib.o and logo.h will be generated in the
|
||||
current directory (the build directory) while logo.bmp comes with the
|
||||
component and resides under the component path. Because logo.h is a
|
||||
generated file, it needs to be cleaned when make clean is called which
|
||||
why it is added to the COMPONENT_EXTRA_CLEAN variable.
|
||||
|
||||
|
||||
This will work just fine, but there's one last cosmetic improvement that
|
||||
can be done. The make system tries to make the make process somewhat
|
||||
easier on the eyes by hiding the commands (unless you run make with the
|
||||
V=1 switch) and this does not do that yet. Here's an improved version
|
||||
that will output in the same style as the rest of the make process:
|
||||
|
||||
----8<----
|
||||
COMPONENT_EXTRA_CLEAN := test_tjpgd_logo.h
|
||||
|
||||
graphics_lib.o: logo.h
|
||||
|
||||
logo.h: $(COMPONENT_PATH)/logo.bmp
|
||||
$(summary) BMP2H $@
|
||||
$(Q) bmp2h -i $^ -o $@
|
||||
|
||||
include $(IDF_PATH)/make/component.mk
|
||||
---->8----
|
||||
|
||||
Obviously, there are cases where all these recipes are insufficient for a
|
||||
certain component, for example when the component is basically a wrapper
|
||||
around another third-party component not originally intended to be
|
||||
compiled under this build system. In that case, it's possible to forego
|
||||
the build system entirely by setting COMPONENT_OWNBUILDTARGET and
|
||||
possibly COMPONENT_OWNCLEANTARGET and defining your own build- and clean
|
||||
target. The build target can do anything as long as it creates
|
||||
$(COMPONENT_LIBRARY) for the main file to link into the project binary,
|
||||
and even that is not necessary: if the COMPONENT_ADD_LDFLAGS variable
|
||||
is set, the component can instruct the linker to do anything else as well.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -49,3 +49,11 @@ The simplest way to use the partition table is to `make menuconfig` and choose o
|
||||
In both cases the factory app is flashed at offset 0x10000. If you `make partition_table` then it will print a summary of the partition table.
|
||||
|
||||
For more details about partition tables and how to create custom variations, view the `docs/partition_tables.rst` file.
|
||||
|
||||
# Resources
|
||||
|
||||
* The [docs directory of the esp-idf repository](https://github.com/espressif/esp-idf/tree/master/docs) contains esp-idf documentation.
|
||||
|
||||
* The [esp32.com forum](http://esp32.com/) is a place to ask questions and find community resources.
|
||||
|
||||
* [Check the Issues section on github](https://github.com/espressif/esp-idf/issues) if you find a bug or have a feature request. Please check existing Issues before opening a new one.
|
||||
|
17
add_path.sh
Normal file
17
add_path.sh
Normal file
@ -0,0 +1,17 @@
|
||||
# This shell snippet appends useful esp-idf tools to your PATH environment
|
||||
# variable. This means you can run esp-idf tools without needing to give the
|
||||
# full path.
|
||||
#
|
||||
# Use this script like this:
|
||||
#
|
||||
# . ${IDF_PATH}/add_path.sh
|
||||
#
|
||||
if [ -z ${IDF_PATH} ]; then
|
||||
echo "IDF_PATH must be set before including this script."
|
||||
else
|
||||
IDF_ADD_PATHS_EXTRAS="${IDF_PATH}/components/esptool_py/esptool:${IDF_PATH}/components/partition_table/"
|
||||
export PATH="${PATH}:${IDF_ADD_PATHS_EXTRAS}"
|
||||
echo "Added to PATH: ${IDF_ADD_PATHS_EXTRAS}"
|
||||
fi
|
||||
|
||||
|
1810
bin/esptool.py
1810
bin/esptool.py
File diff suppressed because it is too large
Load Diff
33
components/bootloader/Kconfig.projbuild
Normal file
33
components/bootloader/Kconfig.projbuild
Normal file
@ -0,0 +1,33 @@
|
||||
menu "Bootloader config"
|
||||
|
||||
choice BOOTLOADER_LOG_LEVEL
|
||||
bool "Bootloader log verbosity"
|
||||
default BOOTLOADER_LOG_LEVEL_NOTICE
|
||||
help
|
||||
Specify how much output to see in the bootloader logs.
|
||||
|
||||
Note that if MTDO is HIGH on reset, all early boot output
|
||||
(including bootloader logs) are suppressed.
|
||||
config BOOTLOADER_LOG_LEVEL_NONE
|
||||
bool "No output"
|
||||
config BOOTLOADER_LOG_LEVEL_ERROR
|
||||
bool "Error"
|
||||
config BOOTLOADER_LOG_LEVEL_WARN
|
||||
bool "Warning"
|
||||
config BOOTLOADER_LOG_LEVEL_INFO
|
||||
bool "Info"
|
||||
config BOOTLOADER_LOG_LEVEL_NOTICE
|
||||
bool "Notice"
|
||||
config BOOTLOADER_LOG_LEVEL_DEBUG
|
||||
bool "Debug"
|
||||
endchoice
|
||||
|
||||
config BOOTLOADER_LOG_COLORS
|
||||
bool "Use ANSI terminal colors in bootloader log output"
|
||||
default "y"
|
||||
help
|
||||
Enable ANSI terminal color codes in bootloader output.
|
||||
|
||||
In order to view these, your terminal program must support ANSI color codes.
|
||||
|
||||
endmenu
|
@ -8,6 +8,7 @@
|
||||
# basically runs Make in the src/ directory but it needs to zero some variables
|
||||
# the ESP-IDF project.mk makefile exports first, to not let them interfere.
|
||||
#
|
||||
ifeq ("$(IS_BOOTLOADER_BUILD)","")
|
||||
|
||||
BOOTLOADER_COMPONENT_PATH := $(COMPONENT_PATH)
|
||||
BOOTLOADER_BUILD_DIR=$(BUILD_DIR_BASE)/bootloader
|
||||
@ -47,3 +48,5 @@ $(COMPONENT_PATH)/src/sdkconfig: $(PROJECT_PATH)/sdkconfig
|
||||
# bootloader-flash calls flash in the bootloader dummy project
|
||||
bootloader-flash: $(BOOTLOADER_BIN)
|
||||
$(MAKE) -C $(BOOTLOADER_COMPONENT_PATH)/src flash MAKEFLAGS= V=$(V)
|
||||
|
||||
endif
|
||||
|
@ -4,7 +4,12 @@
|
||||
#
|
||||
|
||||
PROJECT_NAME := bootloader
|
||||
COMPONENTS := esptool_py
|
||||
COMPONENTS := esptool_py bootloader
|
||||
|
||||
# The bootloader pseudo-component is also included in this build, for its Kconfig.projbuild to be included.
|
||||
#
|
||||
# IS_BOOTLOADER_BUILD tells the component Makefile.projbuild to be a no-op
|
||||
IS_BOOTLOADER_BUILD := 1
|
||||
|
||||
#We cannot include the esp32 component directly but we need its includes. This is fixed by
|
||||
#adding it in the main/Makefile directory.
|
||||
|
@ -19,39 +19,64 @@ extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#define BOOT_LOG_LEVEL_NONE (0)
|
||||
#define BOOT_LOG_LEVEL_ERROR (1)
|
||||
#define BOOT_LOG_LEVEL_WARN (2)
|
||||
#define BOOT_LOG_LEVEL_INFO (3)
|
||||
#define BOOT_LOG_LEVEL_NOTICE (4)
|
||||
#define BOOT_LOG_LEVEL_DEBUG (5)
|
||||
|
||||
#define Black 0;30
|
||||
#define Red 0;31
|
||||
#define Green 0;32
|
||||
#define Brown 0;33
|
||||
#define Blue 0;34
|
||||
#define Purple 0;35
|
||||
#define Cyan 0;36
|
||||
#define Black "30"
|
||||
#define Red "31"
|
||||
#define Green "32"
|
||||
#define Brown "33"
|
||||
#define Blue "34"
|
||||
#define Purple "35"
|
||||
#define Cyan "36"
|
||||
|
||||
// TODO: move BOOT_LOG_LEVEL into menuconfig
|
||||
//#define BOOT_LOG_LEVEL BOOT_LOG_LEVEL_ERROR
|
||||
#define BOOT_LOG_LEVEL BOOT_LOG_LEVEL_NOTICE
|
||||
#if CONFIG_BOOTLOADER_LOG_COLORS
|
||||
#define LOG_COLOR(COLOR) "\033[0;"COLOR"m"
|
||||
#define LOG_BOLD(COLOR) "\033[1;"COLOR"m"
|
||||
#define LOG_RESET_COLOR "\033[0m"
|
||||
#else
|
||||
#define LOG_COLOR(...)
|
||||
#define LOG_BOLD(...)
|
||||
#define LOG_RESET_COLOR ""
|
||||
#endif
|
||||
|
||||
// BOOT_LOG_LEVEL defined by make menuconfig
|
||||
#if CONFIG_BOOTLOADER_LOG_LEVEL_NONE
|
||||
#define BOOT_LOG_LEVEL BOOT_LOG_LEVEL_NONE
|
||||
#elif CONFIG_BOOTLOADER_LOG_LEVEL_ERROR
|
||||
#define BOOT_LOG_LEVEL BOOT_LOG_LEVEL_ERROR
|
||||
#elif CONFIG_BOOTLOADER_LOG_LEVEL_WARN
|
||||
#define BOOT_LOG_LEVEL BOOT_LOG_LEVEL_WARN
|
||||
#elif CONFIG_BOOTLOADER_LOG_LEVEL_INFO
|
||||
#define BOOT_LOG_LEVEL BOOT_LOG_LEVEL_INFO
|
||||
#elif CONFIG_BOOTLOADER_LOG_LEVEL_NOTICE
|
||||
#define BOOT_LOG_LEVEL BOOT_LOG_LEVEL_NOTICE
|
||||
#elif CONFIG_BOOTLOADER_LOG_LEVEL_DEBUG
|
||||
#define BOOT_LOG_LEVEL BOOT_LOG_LEVEL_DEBUG
|
||||
#else
|
||||
#error "No bootloader log level set in menuconfig!"
|
||||
#endif
|
||||
|
||||
//printf("\033[0;36m[NOTICE][%s][%s][%d]\n" format "\r\n", __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__);
|
||||
#define log_notice(format, ...) \
|
||||
do{\
|
||||
if(BOOT_LOG_LEVEL >= BOOT_LOG_LEVEL_NOTICE){\
|
||||
ets_printf("\033[0;36m" format "\r\n", ##__VA_ARGS__);\
|
||||
ets_printf("\033[0m"); \
|
||||
ets_printf(LOG_COLOR(Cyan) format "\r\n", ##__VA_ARGS__); \
|
||||
ets_printf(LOG_RESET_COLOR); \
|
||||
}\
|
||||
}while(0)
|
||||
|
||||
#define log_info(format, ...) \
|
||||
do{\
|
||||
if(BOOT_LOG_LEVEL >= BOOT_LOG_LEVEL_INFO){\
|
||||
ets_printf("\033[1;36m" format "\r\n", ##__VA_ARGS__);\
|
||||
ets_printf("\033[0m"); \
|
||||
ets_printf(LOG_BOLD(Cyan) format "\r\n", ##__VA_ARGS__); \
|
||||
ets_printf(LOG_RESET_COLOR); \
|
||||
}\
|
||||
}while(0)
|
||||
|
||||
@ -59,8 +84,8 @@ extern "C"
|
||||
#define log_error(format, ...) \
|
||||
do{\
|
||||
if(BOOT_LOG_LEVEL >= BOOT_LOG_LEVEL_ERROR){\
|
||||
ets_printf("\033[0;31m[ERROR][%s][%s][%d]\n" format "\r\n", __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__);\
|
||||
ets_printf("\033[0m"); \
|
||||
ets_printf(LOG_COLOR(Red) "[ERROR][%s][%s][%d]\n" format "\r\n", __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
|
||||
ets_printf(LOG_RESET_COLOR); \
|
||||
}\
|
||||
}while(0)
|
||||
|
||||
@ -68,8 +93,8 @@ extern "C"
|
||||
#define log_warn(format, ...) \
|
||||
do{\
|
||||
if(BOOT_LOG_LEVEL >= BOOT_LOG_LEVEL_WARN){\
|
||||
ets_printf("\033[1;33m[WARN][%s][%s][%d]\n" format "\r\n", __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__);\
|
||||
ets_printf("\033[0m"); \
|
||||
ets_printf(LOG_BOLD(Brown) "[WARN][%s][%s][%d]\n" format "\r\n", __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
|
||||
ets_printf(LOG_RESET_COLOR); \
|
||||
}\
|
||||
}while(0)
|
||||
|
||||
@ -77,8 +102,8 @@ extern "C"
|
||||
#define log_debug(format, ...) \
|
||||
do{\
|
||||
if(BOOT_LOG_LEVEL >= BOOT_LOG_LEVEL_DEBUG){\
|
||||
ets_printf("\033[1;32m[DEBUG][%s][%s][%d]\n" format "\r\n", __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
|
||||
ets_printf("\033[0m"); \
|
||||
ets_printf(LOG_BOLD(Green) "[DEBUG][%s][%s][%d]\n" format "\r\n", __FILE__, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
|
||||
ets_printf(LOG_RESET_COLOR); \
|
||||
}\
|
||||
}while(0)
|
||||
|
||||
@ -86,4 +111,4 @@ extern "C"
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __BOOT_LOGGING_H__ */
|
||||
#endif /* __BOOT_LOGGING_H__ */
|
||||
|
@ -276,8 +276,6 @@ void bootloader_main()
|
||||
{
|
||||
//Run start routine.
|
||||
/*ESP32 2ND bootload start here*/
|
||||
|
||||
|
||||
log_info( "\n" );
|
||||
log_info( "**************************************" );
|
||||
log_info( "* hello espressif ESP32! *" );
|
||||
@ -294,7 +292,7 @@ void bootloader_main()
|
||||
log_notice( "compile time %s\n", __TIME__ );
|
||||
/* close watch dog here */
|
||||
REG_CLR_BIT( RTC_WDTCONFIG0, RTC_CNTL_WDT_FLASHBOOT_MOD_EN );
|
||||
REG_CLR_BIT( WDTCONFIG0, TIMERS_WDT_FLASHBOOT_MOD_EN );
|
||||
REG_CLR_BIT( WDTCONFIG0(0), TIMERS_WDT_FLASHBOOT_MOD_EN );
|
||||
SPIUnlock();
|
||||
/*register first sector in drom0 page 0 */
|
||||
boot_cache_redirect( 0, 0x5000 );
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Main Makefile. This is basically the same as a component makefile.
|
||||
#
|
||||
# This Makefile should, at the very least, just include $(IDF_PATH)/make/component.mk. By default,
|
||||
# This Makefile should, at the very least, just include $(IDF_PATH)/make/component_common.mk. By default,
|
||||
# this will take the sources in the src/ directory, compile them and link them into
|
||||
# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable,
|
||||
# please read the esp-idf build system document if you need to do this.
|
||||
@ -10,4 +10,4 @@
|
||||
COMPONENT_ADD_LDFLAGS := -L $(abspath .) -lmain -T esp32.bootloader.ld -T $(IDF_PATH)/components/esp32/ld/esp32.rom.ld
|
||||
COMPONENT_EXTRA_INCLUDES := $(IDF_PATH)/components/esp32/include
|
||||
|
||||
include $(IDF_PATH)/make/component.mk
|
||||
include $(IDF_PATH)/make/component_common.mk
|
@ -7,7 +7,6 @@ config WIFI_ENABLED
|
||||
This compiles in the low-level WiFi stack.
|
||||
|
||||
Temporarily, this option requires that FreeRTOS runs in single core mode.
|
||||
depends on FREERTOS_UNICORE
|
||||
|
||||
config WIFI_AUTO_STARTUP
|
||||
bool "Start WiFi with system startup"
|
||||
|
@ -1,7 +1,7 @@
|
||||
#
|
||||
# Component Makefile
|
||||
#
|
||||
# This Makefile should, at the very least, just include $(IDF_PATH)/make/component.mk. By default,
|
||||
# This Makefile should, at the very least, just include $(IDF_PATH)/make/component_common.mk. By default,
|
||||
# this will take the sources in this directory, compile them and link them into
|
||||
# lib(subdirectory_name).a in the build directory. This behaviour is entirely configurable,
|
||||
# please read the esp-idf build system document if you need to do this.
|
||||
@ -33,18 +33,13 @@ COMPONENT_ADD_LDFLAGS := -lesp32 \
|
||||
-L $(abspath ld) \
|
||||
$(LINKER_SCRIPTS)
|
||||
|
||||
include $(IDF_PATH)/make/component.mk
|
||||
include $(IDF_PATH)/make/component_common.mk
|
||||
|
||||
ALL_LIB_FILES := $(patsubst %,$(COMPONENT_PATH)/lib/lib%.a,$(LIBS))
|
||||
|
||||
# The binary libraries are in a git submodule, so this target will
|
||||
# be invoked if any modules are missing (probably because
|
||||
# git submodule update --init needs to be run).
|
||||
$(ALL_LIB_FILES):
|
||||
$(Q) [ -d ${IDF_PATH}/.git ] || ( @echo "ERROR: Missing libraries in esp32 component. esp-idf must be cloned from git to work."; exit 1 )
|
||||
$(Q) [ -x $(which git) ] || ( @echo "ERROR: Missing libraries in esp32 component. Need to run 'git submodule update --init' in esp-idf root directory."; exit 1 )
|
||||
@echo "Warning: Missing libraries in components/esp32/lib/ submodule. Going to try running 'git submodule update --init' in esp-idf root directory..."
|
||||
cd ${IDF_PATH} && git submodule update --init
|
||||
# automatically trigger a git submodule update
|
||||
# if any libraries are missing
|
||||
$(eval $(call SubmoduleRequiredForFiles,$(ALL_LIB_FILES)))
|
||||
|
||||
# this is a hack to make sure the app is re-linked if the binary
|
||||
# libraries change or are updated. If they change, the main esp32
|
@ -18,6 +18,7 @@
|
||||
#include "esp_err.h"
|
||||
|
||||
#include "rom/ets_sys.h"
|
||||
#include "rom/uart.h"
|
||||
|
||||
#include "soc/dport_reg.h"
|
||||
#include "soc/io_mux_reg.h"
|
||||
@ -36,6 +37,8 @@
|
||||
#include "esp_spi_flash.h"
|
||||
#include "nvs_flash.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_spi_flash.h"
|
||||
#include "esp_ipc.h"
|
||||
|
||||
static void IRAM_ATTR user_start_cpu0(void);
|
||||
static void IRAM_ATTR call_user_start_cpu1();
|
||||
@ -59,11 +62,6 @@ We arrive here after the bootloader finished loading the program from flash. The
|
||||
flash cache is down and the app CPU is in reset. We do have a stack, so we can do the initialization in C.
|
||||
*/
|
||||
|
||||
void Uart_Init(int no);
|
||||
void uartAttach();
|
||||
void ets_set_appcpu_boot_addr(uint32_t ent);
|
||||
int ets_getAppEntry();
|
||||
|
||||
static bool app_cpu_started = false;
|
||||
|
||||
void IRAM_ATTR call_user_start_cpu0() {
|
||||
@ -180,53 +178,55 @@ void IRAM_ATTR call_user_start_cpu1() {
|
||||
user_start_cpu1();
|
||||
}
|
||||
|
||||
extern volatile int port_xSchedulerRunning;
|
||||
extern int xPortStartScheduler();
|
||||
extern volatile int port_xSchedulerRunning[2];
|
||||
|
||||
void user_start_cpu1(void) {
|
||||
//Wait for the freertos initialization is finished on CPU0
|
||||
while (port_xSchedulerRunning == 0) ;
|
||||
ets_printf("Core0 started initializing FreeRTOS. Jumping to scheduler.\n");
|
||||
//Okay, start the scheduler!
|
||||
void IRAM_ATTR user_start_cpu1(void) {
|
||||
// Wait for FreeRTOS initialization to finish on PRO CPU
|
||||
while (port_xSchedulerRunning[0] == 0) {
|
||||
;
|
||||
}
|
||||
ets_printf("Starting scheduler on APP CPU.\n");
|
||||
xPortStartScheduler();
|
||||
}
|
||||
|
||||
extern void (*__init_array_start)(void);
|
||||
extern void (*__init_array_end)(void);
|
||||
|
||||
extern esp_err_t app_main();
|
||||
static void do_global_ctors(void) {
|
||||
void (**p)(void);
|
||||
for(p = &__init_array_start; p != &__init_array_end; ++p)
|
||||
(*p)();
|
||||
}
|
||||
|
||||
extern esp_err_t app_main(void *ctx);
|
||||
|
||||
void user_start_cpu0(void) {
|
||||
ets_setup_syscalls();
|
||||
do_global_ctors();
|
||||
esp_ipc_init();
|
||||
spi_flash_init();
|
||||
|
||||
#if CONFIG_WIFI_ENABLED
|
||||
ets_printf("nvs_flash_init\n");
|
||||
esp_err_t ret = nvs_flash_init(5, 3);
|
||||
if (ret != ESP_OK) {
|
||||
ets_printf("nvs_flash_init fail, ret=%d\n", ret);
|
||||
printf("nvs_flash_init failed, ret=%d\n", ret);
|
||||
}
|
||||
|
||||
system_init();
|
||||
|
||||
esp_event_init(NULL);
|
||||
esp_event_init(NULL, NULL);
|
||||
|
||||
tcpip_adapter_init();
|
||||
#endif
|
||||
|
||||
#if CONFIG_WIFI_ENABLED && CONFIG_WIFI_AUTO_STARTUP
|
||||
#include "esp_wifi.h"
|
||||
esp_wifi_startup(app_main);
|
||||
esp_wifi_startup(app_main, NULL);
|
||||
#else
|
||||
app_main();
|
||||
app_main(NULL);
|
||||
#endif
|
||||
|
||||
ets_printf("Starting scheduler on PRO CPU.\n");
|
||||
vTaskStartScheduler();
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -29,10 +30,13 @@
|
||||
#define ESP32_WORKAROUND 1
|
||||
|
||||
#if CONFIG_WIFI_ENABLED
|
||||
static bool event_init_flag = false;
|
||||
static xQueueHandle g_event_handler = NULL;
|
||||
static system_event_cb_t g_event_handler_cb;
|
||||
|
||||
#define WIFI_DEBUG(...)
|
||||
static system_event_cb_t g_event_handler_cb;
|
||||
static void *g_event_ctx;
|
||||
|
||||
#define WIFI_DEBUG(...)
|
||||
#define WIFI_API_CALL_CHECK(info, api_call, ret) \
|
||||
do{\
|
||||
esp_err_t __err = (api_call);\
|
||||
@ -43,6 +47,7 @@ do{\
|
||||
} while(0)
|
||||
|
||||
typedef esp_err_t (*system_event_handle_fn_t)(system_event_t *e);
|
||||
|
||||
typedef struct {
|
||||
system_event_id_t event_id;
|
||||
system_event_handle_fn_t event_handle;
|
||||
@ -55,7 +60,7 @@ static esp_err_t system_event_sta_start_handle_default(system_event_t *event);
|
||||
static esp_err_t system_event_sta_stop_handle_default(system_event_t *event);
|
||||
static esp_err_t system_event_sta_connected_handle_default(system_event_t *event);
|
||||
static esp_err_t system_event_sta_disconnected_handle_default(system_event_t *event);
|
||||
static esp_err_t system_event_sta_gotip_default(system_event_t *event);
|
||||
static esp_err_t system_event_sta_got_ip_default(system_event_t *event);
|
||||
|
||||
static system_event_handle_t g_system_event_handle_table[] = {
|
||||
{SYSTEM_EVENT_WIFI_READY, NULL},
|
||||
@ -65,7 +70,7 @@ static system_event_handle_t g_system_event_handle_table[] = {
|
||||
{SYSTEM_EVENT_STA_CONNECTED, system_event_sta_connected_handle_default},
|
||||
{SYSTEM_EVENT_STA_DISCONNECTED, system_event_sta_disconnected_handle_default},
|
||||
{SYSTEM_EVENT_STA_AUTHMODE_CHANGE, NULL},
|
||||
{SYSTEM_EVENT_STA_GOTIP, system_event_sta_gotip_default},
|
||||
{SYSTEM_EVENT_STA_GOT_IP, system_event_sta_got_ip_default},
|
||||
{SYSTEM_EVENT_AP_START, system_event_ap_start_handle_default},
|
||||
{SYSTEM_EVENT_AP_STOP, system_event_ap_stop_handle_default},
|
||||
{SYSTEM_EVENT_AP_STACONNECTED, NULL},
|
||||
@ -74,15 +79,15 @@ static system_event_handle_t g_system_event_handle_table[] = {
|
||||
{SYSTEM_EVENT_MAX, NULL},
|
||||
};
|
||||
|
||||
static esp_err_t system_event_sta_gotip_default(system_event_t *event)
|
||||
static esp_err_t system_event_sta_got_ip_default(system_event_t *event)
|
||||
{
|
||||
extern esp_err_t esp_wifi_set_sta_ip(void);
|
||||
WIFI_API_CALL_CHECK("esp_wifi_set_sta_ip", esp_wifi_set_sta_ip(), ESP_OK);
|
||||
|
||||
printf("ip: " IPSTR ", mask: " IPSTR ", gw: " IPSTR "\n",
|
||||
IP2STR(&event->event_info.got_ip.ip_info.ip),
|
||||
IP2STR(&event->event_info.got_ip.ip_info.netmask),
|
||||
IP2STR(&event->event_info.got_ip.ip_info.gw));
|
||||
IP2STR(&event->event_info.got_ip.ip_info.ip),
|
||||
IP2STR(&event->event_info.got_ip.ip_info.netmask),
|
||||
IP2STR(&event->event_info.got_ip.ip_info.gw));
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
@ -132,7 +137,7 @@ esp_err_t system_event_sta_stop_handle_default(system_event_t *event)
|
||||
esp_err_t system_event_sta_connected_handle_default(system_event_t *event)
|
||||
{
|
||||
tcpip_adapter_dhcp_status_t status;
|
||||
|
||||
|
||||
WIFI_API_CALL_CHECK("esp_wifi_reg_rxcb", esp_wifi_reg_rxcb(WIFI_IF_STA, (wifi_rxcb_t)tcpip_adapter_sta_input), ESP_OK);
|
||||
|
||||
tcpip_adapter_up(TCPIP_ADAPTER_IF_STA);
|
||||
@ -150,7 +155,7 @@ esp_err_t system_event_sta_connected_handle_default(system_event_t *event)
|
||||
system_event_t evt;
|
||||
|
||||
//notify event
|
||||
evt.event_id = SYSTEM_EVENT_STA_GOTIP;
|
||||
evt.event_id = SYSTEM_EVENT_STA_GOT_IP;
|
||||
memcpy(&evt.event_info.got_ip.ip_info, &sta_ip, sizeof(tcpip_adapter_ip_info_t));
|
||||
|
||||
esp_event_send(&evt);
|
||||
@ -172,7 +177,7 @@ esp_err_t system_event_sta_disconnected_handle_default(system_event_t *event)
|
||||
static esp_err_t esp_wifi_post_event_to_user(system_event_t *event)
|
||||
{
|
||||
if (g_event_handler_cb) {
|
||||
return (*g_event_handler_cb)(event);
|
||||
return (*g_event_handler_cb)(g_event_ctx, event);
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
@ -187,102 +192,88 @@ static esp_err_t esp_system_event_debug(system_event_t *event)
|
||||
|
||||
WIFI_DEBUG("received event: ");
|
||||
switch (event->event_id) {
|
||||
case SYSTEM_EVENT_WIFI_READY:
|
||||
{
|
||||
WIFI_DEBUG("SYSTEM_EVENT_WIFI_READY\n");
|
||||
break;
|
||||
}
|
||||
case SYSTEM_EVENT_SCAN_DONE:
|
||||
{
|
||||
system_event_sta_scan_done_t *scan_done;
|
||||
scan_done = &event->event_info.scan_done;
|
||||
WIFI_DEBUG("SYSTEM_EVENT_SCAN_DONE\nstatus:%d, number:%d\n", scan_done->status, scan_done->number);
|
||||
break;
|
||||
}
|
||||
case SYSTEM_EVENT_STA_START:
|
||||
{
|
||||
WIFI_DEBUG("SYSTEM_EVENT_STA_START\n");
|
||||
break;
|
||||
}
|
||||
case SYSTEM_EVENT_STA_STOP:
|
||||
{
|
||||
WIFI_DEBUG("SYSTEM_EVENT_STA_STOP\n");
|
||||
break;
|
||||
}
|
||||
case SYSTEM_EVENT_STA_CONNECTED:
|
||||
{
|
||||
system_event_sta_connected_t *connected;
|
||||
connected = &event->event_info.connected;
|
||||
WIFI_DEBUG("SYSTEM_EVENT_STA_CONNECTED\nssid:%s, ssid_len:%d, bssid:%02x:%02x:%02x:%02x:%02x:%02x, channel:%d, authmode:%d\n", \
|
||||
connected->ssid, connected->ssid_len, connected->bssid[0], connected->bssid[0], connected->bssid[1], \
|
||||
connected->bssid[3], connected->bssid[4], connected->bssid[5], connected->channel, connected->authmode);
|
||||
break;
|
||||
}
|
||||
case SYSTEM_EVENT_STA_DISCONNECTED:
|
||||
{
|
||||
system_event_sta_disconnected_t *disconnected;
|
||||
disconnected = &event->event_info.disconnected;
|
||||
WIFI_DEBUG("SYSTEM_EVENT_STA_DISCONNECTED\nssid:%s, ssid_len:%d, bssid:%02x:%02x:%02x:%02x:%02x:%02x, reason:%d\n", \
|
||||
disconnected->ssid, disconnected->ssid_len, disconnected->bssid[0], disconnected->bssid[0], disconnected->bssid[1], \
|
||||
disconnected->bssid[3], disconnected->bssid[4], disconnected->bssid[5], disconnected->reason);
|
||||
break;
|
||||
}
|
||||
case SYSTEM_EVENT_STA_AUTHMODE_CHANGE:
|
||||
{
|
||||
system_event_sta_authmode_change_t *auth_change;
|
||||
auth_change = &event->event_info.auth_change;
|
||||
WIFI_DEBUG("SYSTEM_EVENT_STA_AUTHMODE_CHNAGE\nold_mode:%d, new_mode:%d\n", auth_change->old_mode, auth_change->new_mode);
|
||||
break;
|
||||
}
|
||||
case SYSTEM_EVENT_STA_GOTIP:
|
||||
{
|
||||
system_event_sta_got_ip_t *got_ip;
|
||||
got_ip = &event->event_info.got_ip;
|
||||
WIFI_DEBUG("SYSTEM_EVENT_STA_GOTIP\n");
|
||||
break;
|
||||
}
|
||||
case SYSTEM_EVENT_AP_START:
|
||||
{
|
||||
WIFI_DEBUG("SYSTEM_EVENT_AP_START\n");
|
||||
break;
|
||||
}
|
||||
case SYSTEM_EVENT_AP_STOP:
|
||||
{
|
||||
WIFI_DEBUG("SYSTEM_EVENT_AP_STOP\n");
|
||||
break;
|
||||
}
|
||||
case SYSTEM_EVENT_AP_STACONNECTED:
|
||||
{
|
||||
system_event_ap_staconnected_t *staconnected;
|
||||
staconnected = &event->event_info.sta_connected;
|
||||
WIFI_DEBUG("SYSTEM_EVENT_AP_STACONNECTED\nmac:%02x:%02x:%02x:%02x:%02x:%02x, aid:%d\n", \
|
||||
staconnected->mac[0], staconnected->mac[0], staconnected->mac[1], \
|
||||
staconnected->mac[3], staconnected->mac[4], staconnected->mac[5], staconnected->aid);
|
||||
break;
|
||||
}
|
||||
case SYSTEM_EVENT_AP_STADISCONNECTED:
|
||||
{
|
||||
system_event_ap_stadisconnected_t *stadisconnected;
|
||||
stadisconnected = &event->event_info.sta_disconnected;
|
||||
WIFI_DEBUG("SYSTEM_EVENT_AP_STADISCONNECTED\nmac:%02x:%02x:%02x:%02x:%02x:%02x, aid:%d\n", \
|
||||
stadisconnected->mac[0], stadisconnected->mac[0], stadisconnected->mac[1], \
|
||||
stadisconnected->mac[3], stadisconnected->mac[4], stadisconnected->mac[5], stadisconnected->aid);
|
||||
break;
|
||||
}
|
||||
case SYSTEM_EVENT_AP_PROBEREQRECVED:
|
||||
{
|
||||
system_event_ap_probe_req_rx_t *ap_probereqrecved;
|
||||
ap_probereqrecved = &event->event_info.ap_probereqrecved;
|
||||
WIFI_DEBUG("SYSTEM_EVENT_AP_PROBEREQRECVED\nrssi:%d, mac:%02x:%02x:%02x:%02x:%02x:%02x\n", \
|
||||
ap_probereqrecved->rssi, ap_probereqrecved->mac[0], ap_probereqrecved->mac[0], ap_probereqrecved->mac[1], \
|
||||
ap_probereqrecved->mac[3], ap_probereqrecved->mac[4], ap_probereqrecved->mac[5]);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
printf("Error: no such kind of event!\n");
|
||||
break;
|
||||
}
|
||||
case SYSTEM_EVENT_WIFI_READY: {
|
||||
WIFI_DEBUG("SYSTEM_EVENT_WIFI_READY\n");
|
||||
break;
|
||||
}
|
||||
case SYSTEM_EVENT_SCAN_DONE: {
|
||||
system_event_sta_scan_done_t *scan_done;
|
||||
scan_done = &event->event_info.scan_done;
|
||||
WIFI_DEBUG("SYSTEM_EVENT_SCAN_DONE\nstatus:%d, number:%d\n", scan_done->status, scan_done->number);
|
||||
break;
|
||||
}
|
||||
case SYSTEM_EVENT_STA_START: {
|
||||
WIFI_DEBUG("SYSTEM_EVENT_STA_START\n");
|
||||
break;
|
||||
}
|
||||
case SYSTEM_EVENT_STA_STOP: {
|
||||
WIFI_DEBUG("SYSTEM_EVENT_STA_STOP\n");
|
||||
break;
|
||||
}
|
||||
case SYSTEM_EVENT_STA_CONNECTED: {
|
||||
system_event_sta_connected_t *connected;
|
||||
connected = &event->event_info.connected;
|
||||
WIFI_DEBUG("SYSTEM_EVENT_STA_CONNECTED\nssid:%s, ssid_len:%d, bssid:%02x:%02x:%02x:%02x:%02x:%02x, channel:%d, authmode:%d\n", \
|
||||
connected->ssid, connected->ssid_len, connected->bssid[0], connected->bssid[0], connected->bssid[1], \
|
||||
connected->bssid[3], connected->bssid[4], connected->bssid[5], connected->channel, connected->authmode);
|
||||
break;
|
||||
}
|
||||
case SYSTEM_EVENT_STA_DISCONNECTED: {
|
||||
system_event_sta_disconnected_t *disconnected;
|
||||
disconnected = &event->event_info.disconnected;
|
||||
WIFI_DEBUG("SYSTEM_EVENT_STA_DISCONNECTED\nssid:%s, ssid_len:%d, bssid:%02x:%02x:%02x:%02x:%02x:%02x, reason:%d\n", \
|
||||
disconnected->ssid, disconnected->ssid_len, disconnected->bssid[0], disconnected->bssid[0], disconnected->bssid[1], \
|
||||
disconnected->bssid[3], disconnected->bssid[4], disconnected->bssid[5], disconnected->reason);
|
||||
break;
|
||||
}
|
||||
case SYSTEM_EVENT_STA_AUTHMODE_CHANGE: {
|
||||
system_event_sta_authmode_change_t *auth_change;
|
||||
auth_change = &event->event_info.auth_change;
|
||||
WIFI_DEBUG("SYSTEM_EVENT_STA_AUTHMODE_CHNAGE\nold_mode:%d, new_mode:%d\n", auth_change->old_mode, auth_change->new_mode);
|
||||
break;
|
||||
}
|
||||
case SYSTEM_EVENT_STA_GOT_IP: {
|
||||
system_event_sta_got_ip_t *got_ip;
|
||||
got_ip = &event->event_info.got_ip;
|
||||
WIFI_DEBUG("SYSTEM_EVENT_STA_GOTIP\n");
|
||||
break;
|
||||
}
|
||||
case SYSTEM_EVENT_AP_START: {
|
||||
WIFI_DEBUG("SYSTEM_EVENT_AP_START\n");
|
||||
break;
|
||||
}
|
||||
case SYSTEM_EVENT_AP_STOP: {
|
||||
WIFI_DEBUG("SYSTEM_EVENT_AP_STOP\n");
|
||||
break;
|
||||
}
|
||||
case SYSTEM_EVENT_AP_STACONNECTED: {
|
||||
system_event_ap_staconnected_t *staconnected;
|
||||
staconnected = &event->event_info.sta_connected;
|
||||
WIFI_DEBUG("SYSTEM_EVENT_AP_STACONNECTED\nmac:%02x:%02x:%02x:%02x:%02x:%02x, aid:%d\n", \
|
||||
staconnected->mac[0], staconnected->mac[0], staconnected->mac[1], \
|
||||
staconnected->mac[3], staconnected->mac[4], staconnected->mac[5], staconnected->aid);
|
||||
break;
|
||||
}
|
||||
case SYSTEM_EVENT_AP_STADISCONNECTED: {
|
||||
system_event_ap_stadisconnected_t *stadisconnected;
|
||||
stadisconnected = &event->event_info.sta_disconnected;
|
||||
WIFI_DEBUG("SYSTEM_EVENT_AP_STADISCONNECTED\nmac:%02x:%02x:%02x:%02x:%02x:%02x, aid:%d\n", \
|
||||
stadisconnected->mac[0], stadisconnected->mac[0], stadisconnected->mac[1], \
|
||||
stadisconnected->mac[3], stadisconnected->mac[4], stadisconnected->mac[5], stadisconnected->aid);
|
||||
break;
|
||||
}
|
||||
case SYSTEM_EVENT_AP_PROBEREQRECVED: {
|
||||
system_event_ap_probe_req_rx_t *ap_probereqrecved;
|
||||
ap_probereqrecved = &event->event_info.ap_probereqrecved;
|
||||
WIFI_DEBUG("SYSTEM_EVENT_AP_PROBEREQRECVED\nrssi:%d, mac:%02x:%02x:%02x:%02x:%02x:%02x\n", \
|
||||
ap_probereqrecved->rssi, ap_probereqrecved->mac[0], ap_probereqrecved->mac[0], ap_probereqrecved->mac[1], \
|
||||
ap_probereqrecved->mac[3], ap_probereqrecved->mac[4], ap_probereqrecved->mac[5]);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
printf("Error: no such kind of event!\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
@ -296,8 +287,8 @@ static esp_err_t esp_system_event_handler(system_event_t *event)
|
||||
}
|
||||
|
||||
esp_system_event_debug(event);
|
||||
if ((event->event_id < SYSTEM_EVENT_MAX) && (event->event_id == g_system_event_handle_table[event->event_id].event_id)){
|
||||
if (g_system_event_handle_table[event->event_id].event_handle){
|
||||
if ((event->event_id < SYSTEM_EVENT_MAX) && (event->event_id == g_system_event_handle_table[event->event_id].event_id)) {
|
||||
if (g_system_event_handle_table[event->event_id].event_handle) {
|
||||
WIFI_DEBUG("enter default callback\n");
|
||||
g_system_event_handle_table[event->event_id].event_handle(event);
|
||||
WIFI_DEBUG("exit default callback\n");
|
||||
@ -317,42 +308,57 @@ static void esp_system_event_task(void *pvParameters)
|
||||
while (1) {
|
||||
if (xQueueReceive(g_event_handler, &evt, portMAX_DELAY) == pdPASS) {
|
||||
ret = esp_system_event_handler(&evt);
|
||||
if (ret == ESP_FAIL)
|
||||
if (ret == ESP_FAIL) {
|
||||
printf("esp wifi post event to user fail!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
system_event_cb_t esp_event_set_cb(system_event_cb_t cb)
|
||||
system_event_cb_t esp_event_set_cb(system_event_cb_t cb, void *ctx)
|
||||
{
|
||||
system_event_cb_t old_cb = g_event_handler_cb;
|
||||
|
||||
g_event_handler_cb = cb;
|
||||
g_event_ctx = ctx;
|
||||
|
||||
return old_cb;
|
||||
}
|
||||
|
||||
esp_err_t esp_event_send(system_event_t *event)
|
||||
{
|
||||
portBASE_TYPE ret;
|
||||
|
||||
|
||||
ret = xQueueSendToBack((xQueueHandle)g_event_handler, event, 0);
|
||||
if (pdPASS != ret){
|
||||
if (event) printf("e=%d f\n", event->event_id);
|
||||
else printf("e null\n");
|
||||
|
||||
if (pdPASS != ret) {
|
||||
if (event) {
|
||||
printf("e=%d f\n", event->event_id);
|
||||
} else {
|
||||
printf("e null\n");
|
||||
}
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void* esp_event_get_handler(void)
|
||||
void *esp_event_get_handler(void)
|
||||
{
|
||||
return (void*)g_event_handler;
|
||||
return (void *)g_event_handler;
|
||||
}
|
||||
|
||||
esp_err_t esp_event_init(system_event_cb_t cb)
|
||||
esp_err_t esp_event_init(system_event_cb_t cb, void *ctx)
|
||||
{
|
||||
g_event_handler_cb = (system_event_cb_t)cb;
|
||||
if (event_init_flag) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
g_event_handler_cb = cb;
|
||||
g_event_ctx = ctx;
|
||||
|
||||
g_event_handler = xQueueCreate(CONFIG_WIFI_ENENT_QUEUE_SIZE, sizeof(system_event_t));
|
||||
|
||||
xTaskCreatePinnedToCore(esp_system_event_task, "eventTask", CONFIG_WIFI_EVENT_TASK_STACK_SIZE, NULL, 5, NULL, 0); // TODO: rearrange task priority
|
||||
return ESP_OK;
|
||||
}
|
||||
|
@ -27,7 +27,10 @@ typedef int32_t esp_err_t;
|
||||
#define ESP_OK 0
|
||||
#define ESP_FAIL -1
|
||||
|
||||
#define ESP_ERR_NO_MEM 0x101
|
||||
#define ESP_ERR_NO_MEM 0x101
|
||||
#define ESP_ERR_INVALID_ARG 0x102
|
||||
#define ESP_ERR_INVALID_STATE 0x103
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
84
components/esp32/include/esp_event.h
Executable file → Normal file
84
components/esp32/include/esp_event.h
Executable file → Normal file
@ -28,24 +28,24 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
SYSTEM_EVENT_WIFI_READY = 0, /**< ESP32 wifi ready */
|
||||
SYSTEM_EVENT_WIFI_READY = 0, /**< ESP32 WiFi ready */
|
||||
SYSTEM_EVENT_SCAN_DONE, /**< ESP32 finish scanning AP */
|
||||
SYSTEM_EVENT_STA_START, /**< ESP32 station start */
|
||||
SYSTEM_EVENT_STA_STOP, /**< ESP32 station start */
|
||||
SYSTEM_EVENT_STA_STOP, /**< ESP32 station stop */
|
||||
SYSTEM_EVENT_STA_CONNECTED, /**< ESP32 station connected to AP */
|
||||
SYSTEM_EVENT_STA_DISCONNECTED, /**< ESP32 station disconnected to AP */
|
||||
SYSTEM_EVENT_STA_DISCONNECTED, /**< ESP32 station disconnected from AP */
|
||||
SYSTEM_EVENT_STA_AUTHMODE_CHANGE, /**< the auth mode of AP connected by ESP32 station changed */
|
||||
SYSTEM_EVENT_STA_GOTIP, /**< ESP32 station received IP address */
|
||||
SYSTEM_EVENT_AP_START, /**< ESP32 softap start */
|
||||
SYSTEM_EVENT_AP_STOP, /**< ESP32 softap start */
|
||||
SYSTEM_EVENT_STA_GOT_IP, /**< ESP32 station got IP from connected AP */
|
||||
SYSTEM_EVENT_AP_START, /**< ESP32 soft-AP start */
|
||||
SYSTEM_EVENT_AP_STOP, /**< ESP32 soft-AP stop */
|
||||
SYSTEM_EVENT_AP_STACONNECTED, /**< a station connected to ESP32 soft-AP */
|
||||
SYSTEM_EVENT_AP_STADISCONNECTED, /**< a station disconnected to ESP32 soft-AP */
|
||||
SYSTEM_EVENT_AP_STADISCONNECTED, /**< a station disconnected from ESP32 soft-AP */
|
||||
SYSTEM_EVENT_AP_PROBEREQRECVED, /**< Receive probe request packet in soft-AP interface */
|
||||
SYSTEM_EVENT_MAX
|
||||
} system_event_id_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t status; /**< status of scanning APs*/
|
||||
uint32_t status; /**< status of scanning APs */
|
||||
uint8_t number;
|
||||
uint8_t scan_id;
|
||||
} system_event_sta_scan_done_t;
|
||||
@ -94,10 +94,10 @@ typedef union {
|
||||
system_event_sta_disconnected_t disconnected; /**< ESP32 station disconnected to AP */
|
||||
system_event_sta_scan_done_t scan_done; /**< ESP32 station scan (APs) done */
|
||||
system_event_sta_authmode_change_t auth_change; /**< the auth mode of AP ESP32 station connected to changed */
|
||||
system_event_sta_got_ip_t got_ip;
|
||||
system_event_sta_got_ip_t got_ip; /**< ESP32 station got IP */
|
||||
system_event_ap_staconnected_t sta_connected; /**< a station connected to ESP32 soft-AP */
|
||||
system_event_ap_stadisconnected_t sta_disconnected; /**< a station disconnected to ESP32 soft-AP */
|
||||
system_event_ap_probe_req_rx_t ap_probereqrecved; /**< ESP32 softAP receive probe request packet */
|
||||
system_event_ap_probe_req_rx_t ap_probereqrecved; /**< ESP32 soft-AP receive probe request packet */
|
||||
} system_event_info_t;
|
||||
|
||||
typedef struct {
|
||||
@ -105,11 +105,65 @@ typedef struct {
|
||||
system_event_info_t event_info; /**< event information */
|
||||
} system_event_t;
|
||||
|
||||
typedef esp_err_t (*system_event_cb_t)(system_event_t *event);
|
||||
system_event_cb_t esp_event_set_cb(system_event_cb_t cb);
|
||||
esp_err_t esp_event_send(system_event_t * event);
|
||||
void* esp_event_get_handler(void);
|
||||
esp_err_t esp_event_init(system_event_cb_t cb);
|
||||
/**
|
||||
* @brief Application specified event callback function
|
||||
*
|
||||
* @param void *ctx : reserved for user
|
||||
* @param system_event_t *event : event type defined in this file
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
typedef esp_err_t (*system_event_cb_t)(void *ctx, system_event_t *event);
|
||||
|
||||
/**
|
||||
* @brief Set application specified event callback function
|
||||
*
|
||||
* @attention 1. If cb is NULL, means application don't need to handle
|
||||
* If cb is not NULL, it will be call when an event is received, after the default event callback is completed
|
||||
*
|
||||
* @param system_event_cb_t cb : callback
|
||||
* @param void *ctx : reserved for user
|
||||
*
|
||||
* @return system_event_cb_t : old callback
|
||||
*/
|
||||
system_event_cb_t esp_event_set_cb(system_event_cb_t cb, void *ctx);
|
||||
|
||||
/**
|
||||
* @brief Send a event to event task
|
||||
*
|
||||
* @attention 1. Other task/modules, such as the TCPIP module, can call this API to send an event to event task
|
||||
*
|
||||
* @param system_event_t * event : event
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_event_send(system_event_t *event);
|
||||
|
||||
/**
|
||||
* @brief Get the event handler
|
||||
*
|
||||
* @attention : currently this API returns event queue handler, by this event queue,
|
||||
* users can notice when WiFi has done something like scanning done, connected to AP or disconnected from AP.
|
||||
*
|
||||
* @param null
|
||||
*
|
||||
* @return void * : event queue pointer
|
||||
*/
|
||||
void *esp_event_get_handler(void);
|
||||
|
||||
/**
|
||||
* @brief Init the event module
|
||||
* Create the event handler and task
|
||||
*
|
||||
* @param system_event_cb_t cb : application specified event callback, it can be modified by call esp_event_set_cb
|
||||
* @param void *ctx : reserved for user
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_event_init(system_event_cb_t cb, void *ctx);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -61,8 +61,8 @@ extern "C" {
|
||||
#define ESP_GPIO_INTR_ATTACH(func, arg) \
|
||||
xt_set_interrupt_handler(ETS_GPIO_INUM, (func), (void *)(arg))
|
||||
|
||||
#define ESP_UART_INTR_ATTACH(func, arg) \
|
||||
xt_set_interrupt_handler(ETS_UART_INUM, (func), (void *)(arg))
|
||||
#define ESP_UART0_INTR_ATTACH(func, arg) \
|
||||
xt_set_interrupt_handler(ETS_UART0_INUM, (func), (void *)(arg))
|
||||
|
||||
#define ESP_WDT_INTR_ATTACH(func, arg) \
|
||||
xt_set_interrupt_handler(ETS_WDT_INUM, (func), (void *)(arg))
|
||||
@ -142,11 +142,11 @@ extern "C" {
|
||||
#define ESP_BB_INTR_DISABLE() \
|
||||
ESP_INTR_DISABLE(ETS_BB_INUM)
|
||||
|
||||
#define ESP_UART_INTR_ENABLE() \
|
||||
ESP_INTR_ENABLE(ETS_UART_INUM)
|
||||
#define ESP_UART0_INTR_ENABLE() \
|
||||
ESP_INTR_ENABLE(ETS_UART0_INUM)
|
||||
|
||||
#define ESP_UART_INTR_DISABLE() \
|
||||
ESP_INTR_DISABLE(ETS_UART_INUM)
|
||||
#define ESP_UART0_INTR_DISABLE() \
|
||||
ESP_INTR_DISABLE(ETS_UART0_INUM)
|
||||
|
||||
#define ESP_LEDC_INTR_ENABLE() \
|
||||
ESP_INTR_ENABLE(ETS_LEDC_INUM)
|
||||
|
88
components/esp32/include/esp_ipc.h
Normal file
88
components/esp32/include/esp_ipc.h
Normal file
@ -0,0 +1,88 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef __ESP_IPC_H__
|
||||
#define __ESP_IPC_H__
|
||||
|
||||
#include <esp_err.h>
|
||||
|
||||
typedef void (*esp_ipc_func_t)(void* arg);
|
||||
|
||||
/**
|
||||
* @brief Inter-processor call APIs
|
||||
*
|
||||
* FreeRTOS provides several APIs which can be used to communicate between
|
||||
* different tasks, including tasks running on different CPUs.
|
||||
* This module provides additional APIs to run some code on the other CPU.
|
||||
*
|
||||
* These APIs can only be used when FreeRTOS scheduler is running.
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initialize inter-processor call module.
|
||||
*
|
||||
* This function start two tasks, one on each CPU. These tasks are started
|
||||
* with high priority. These tasks are normally inactive, waiting until one of
|
||||
* the esp_ipc_call_* functions to be used. One of these tasks will be
|
||||
* woken up to execute the callback provided to esp_ipc_call_nonblocking or
|
||||
* esp_ipc_call_blocking.
|
||||
*/
|
||||
void esp_ipc_init();
|
||||
|
||||
|
||||
/**
|
||||
* @brief Execute function on the given CPU
|
||||
*
|
||||
* This will wake a high-priority task on CPU indicated by cpu_id argument,
|
||||
* and run func(arg) in the context of that task.
|
||||
* This function returns as soon as the high-priority task is woken up.
|
||||
* If another IPC call is already being executed, this function will also wait
|
||||
* for it to complete.
|
||||
*
|
||||
* In single-core mode, returns ESP_ERR_INVALID_ARG for cpu_id 1.
|
||||
*
|
||||
* @param cpu_id CPU where function should be executed (0 or 1)
|
||||
* @param func pointer to a function which should be executed
|
||||
* @param arg arbitrary argument to be passed into function
|
||||
*
|
||||
* @return ESP_ERR_INVALID_ARG if cpu_id is invalid
|
||||
* ESP_ERR_INVALID_STATE if FreeRTOS scheduler is not running
|
||||
* ESP_OK otherwise
|
||||
*/
|
||||
esp_err_t esp_ipc_call(uint32_t cpu_id, esp_ipc_func_t func, void* arg);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Execute function on the given CPU and wait for it to finish
|
||||
*
|
||||
* This will wake a high-priority task on CPU indicated by cpu_id argument,
|
||||
* and run func(arg) in the context of that task.
|
||||
* This function waits for func to return.
|
||||
*
|
||||
* In single-core mode, returns ESP_ERR_INVALID_ARG for cpu_id 1.
|
||||
*
|
||||
* @param cpu_id CPU where function should be executed (0 or 1)
|
||||
* @param func pointer to a function which should be executed
|
||||
* @param arg arbitrary argument to be passed into function
|
||||
*
|
||||
* @return ESP_ERR_INVALID_ARG if cpu_id is invalid
|
||||
* ESP_ERR_INVALID_STATE if FreeRTOS scheduler is not running
|
||||
* ESP_OK otherwise
|
||||
*/
|
||||
esp_err_t esp_ipc_call_blocking(uint32_t cpu_id, esp_ipc_func_t func, void* arg);
|
||||
|
||||
|
||||
|
||||
#endif /* __ESP_IPC_H__ */
|
494
components/esp32/include/esp_wifi.h
Executable file → Normal file
494
components/esp32/include/esp_wifi.h
Executable file → Normal file
@ -12,6 +12,48 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
/* Notes about WiFi Programming
|
||||
*
|
||||
* The esp32 WiFi programming model can be depicted as following picture:
|
||||
*
|
||||
*
|
||||
* default handler user handler
|
||||
* ------------- --------------- ---------------
|
||||
* | | event | | callback or | |
|
||||
* | tcpip | ---------> | event | ----------> | application |
|
||||
* | stack | | task | event | task |
|
||||
* |-----------| |-------------| |-------------|
|
||||
* /|\ |
|
||||
* | |
|
||||
* event | |
|
||||
* | |
|
||||
* | |
|
||||
* --------------- |
|
||||
* | | |
|
||||
* | WiFi Driver |/__________________|
|
||||
* | |\ API call
|
||||
* | |
|
||||
* |-------------|
|
||||
*
|
||||
* The WiFi driver can be consider as black box, it knows nothing about the high layer code, such as
|
||||
* TCPIP stack, application task, event task etc, all it can do is to receive API call from high layer
|
||||
* or post event queue to a specified Queue, which is initialized by API esp_wifi_init().
|
||||
*
|
||||
* The event task is a daemon task, which receives events from WiFi driver or from other subsystem, such
|
||||
* as TCPIP stack, event task will call the default callback function on receiving the event. For example,
|
||||
* on receiving event SYSTEM_EVENT_STA_CONNECTED, it will call tcpip_adapter_start() to start the DHCP
|
||||
* client in it's default handler.
|
||||
*
|
||||
* Application can register it's own event callback function by API esp_event_init, then the application callback
|
||||
* function will be called after the default callback. Also, if application doesn't want to execute the callback
|
||||
* in the event task, what it needs to do is to post the related event to application task in the application callback function.
|
||||
*
|
||||
* The application task (code) generally mixes all these thing together, it calls APIs to init the system/WiFi and
|
||||
* handle the events when necessary.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __ESP_WIFI_H__
|
||||
#define __ESP_WIFI_H__
|
||||
|
||||
@ -40,10 +82,10 @@ typedef enum {
|
||||
} wifi_interface_t;
|
||||
|
||||
typedef enum {
|
||||
WIFI_COUNTRY_CN = 0,
|
||||
WIFI_COUNTRY_JP,
|
||||
WIFI_COUNTRY_US,
|
||||
WIFI_COUNTRY_EU,
|
||||
WIFI_COUNTRY_CN = 0, /**< country China, channel range [1, 14] */
|
||||
WIFI_COUNTRY_JP, /**< country Japan, channel range [1, 14] */
|
||||
WIFI_COUNTRY_US, /**< country USA, channel range [1, 11] */
|
||||
WIFI_COUNTRY_EU, /**< country Europe, channel range [1, 13] */
|
||||
WIFI_COUNTRY_MAX
|
||||
} wifi_country_t;
|
||||
|
||||
@ -89,54 +131,205 @@ enum {
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
WIFI_SECOND_CHAN_NONE = 0,
|
||||
WIFI_SECOND_CHAN_ABOVE,
|
||||
WIFI_SECOND_CHAN_BELOW,
|
||||
WIFI_SECOND_CHAN_NONE = 0, /**< the channel width is HT20 */
|
||||
WIFI_SECOND_CHAN_ABOVE, /**< the channel width is HT40 and the second channel is above the primary channel */
|
||||
WIFI_SECOND_CHAN_BELOW, /**< the channel width is HT40 and the second channel is below the primary channel */
|
||||
} wifi_second_chan_t;
|
||||
|
||||
typedef esp_err_t (* wifi_startup_cb_t)(void);
|
||||
/**
|
||||
* @brief startup WiFi driver and register application specific callback function
|
||||
*
|
||||
* @attention 1. This API should be called in application startup code to init WiFi driver
|
||||
* @attention 2. The callback function is used to provide application specific WiFi configuration,
|
||||
* such as, set the WiFi mode, register the event callback, set AP SSID etc before
|
||||
* WiFi is startup
|
||||
* @attention 3. Avoid to create application task in the callback, otherwise you may get wrong behavior
|
||||
* @attention 4. If the callback return is not ESP_OK, the startup will fail!
|
||||
* @attention 5. Before this API can be called, system_init()/esp_event_init()/tcpip_adapter_init() should
|
||||
* be called firstly
|
||||
*
|
||||
* @param wifi_startup_cb_t cb : application specific callback function
|
||||
* @param void *ctx : reserved for user
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
typedef esp_err_t (* wifi_startup_cb_t)(void *ctx);
|
||||
|
||||
void esp_wifi_startup(wifi_startup_cb_t cb);
|
||||
esp_err_t esp_wifi_startup(wifi_startup_cb_t cb, void *ctx);
|
||||
|
||||
typedef struct {
|
||||
void *event_q;
|
||||
void *event_q; /**< WiFi event q handler, it's a freeRTOS queue */
|
||||
uint8_t rx_ba_win; /**< TBC */
|
||||
uint8_t tx_ba_win; /**< TBC */
|
||||
uint8_t rx_buf_cnt; /**< TBC */
|
||||
uint8_t tx_buf_cnt; /**< TBC */
|
||||
} wifi_init_config_t;
|
||||
|
||||
/**
|
||||
* @brief Init WiFi
|
||||
* Alloc resource for WiFi driver, such as WiFi control structure, RX/TX buffer,
|
||||
* WiFi NVS structure etc, this WiFi also start WiFi task
|
||||
*
|
||||
* @attention 1. This API must be called before all other WiFi API can be called
|
||||
* @attention 2. Generally we should init event_q in *config, WiFi driver will post the event
|
||||
* to this queue when event happens, such as, when station connects to WiFi, WiFi driver
|
||||
* will post station connected event to this queue. If the queue is not initialized, WiFi
|
||||
* will not post any events
|
||||
* @attention 3. For other parameters, currently it's not ready, just ignore it.
|
||||
*
|
||||
* @param wifi_init_config_t *config : provide WiFi init configuration
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_wifi_init(wifi_init_config_t *config);
|
||||
|
||||
/**
|
||||
* @brief Deinit WiFi
|
||||
* Free all resource allocated in esp_wifi_init and stop WiFi task
|
||||
*
|
||||
* @attention 1. This API should be called if you want to remove WiFi driver from the system
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_wifi_deinit(void);
|
||||
|
||||
/**
|
||||
* @brief Set the WiFi operating mode
|
||||
*
|
||||
* Set the WiFi operating mode as station, soft-AP or station+soft-AP,
|
||||
* The default mode is soft-AP mode.
|
||||
*
|
||||
* @param wifi_mode_t mode : WiFi operating modes:
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_wifi_set_mode(wifi_mode_t mode);
|
||||
|
||||
/**
|
||||
* @brief Get current operating mode of WiFi
|
||||
*
|
||||
* @param wifi_mode_t *mode : store current WiFi mode
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_wifi_get_mode(wifi_mode_t *mode);
|
||||
|
||||
/**
|
||||
* @brief Start WiFi according to current configuration
|
||||
* If mode is WIFI_MODE_STA, it create station control block and start station
|
||||
* If mode is WIFI_MODE_AP, it create soft-AP control block and start soft-AP
|
||||
* If mode is WIFI_MODE_APSTA, it create soft-AP and station control block and start soft-AP and station
|
||||
*
|
||||
* @param null
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_wifi_start(void);
|
||||
|
||||
/**
|
||||
* @brief Stop WiFi
|
||||
If mode is WIFI_MODE_STA, it stop station and free station control block
|
||||
* If mode is WIFI_MODE_AP, it stop soft-AP and free soft-AP control block
|
||||
* If mode is WIFI_MODE_APSTA, it stop station/soft-AP and free station/soft-AP control block
|
||||
*
|
||||
* @param null
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_wifi_stop(void);
|
||||
|
||||
/**
|
||||
* @brief Connect the ESP32 WiFi station to the AP.
|
||||
*
|
||||
* @attention 1. This API only impact WIFI_MODE_STA or WIFI_MODE_APSTA mode
|
||||
* @attention 2. If the ESP32 is connected to an AP, call esp_wifi_disconnect to disconnect.
|
||||
*
|
||||
* @param null
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_wifi_connect(void);
|
||||
|
||||
/**
|
||||
* @brief Disconnect the ESP32 WiFi station from the AP.
|
||||
*
|
||||
* @param null
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_wifi_disconnect(void);
|
||||
|
||||
/**
|
||||
* @brief Currently this API is just an stub API
|
||||
*
|
||||
* @param null
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_wifi_clear_fast_connect(void);
|
||||
|
||||
/**
|
||||
* @brief Kick the all station or associated id equals to aid
|
||||
*
|
||||
* @param uint16_t aid : when aid is 0, kick all stations, otherwise kick station whose associated id is aid
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_wifi_kick_station(uint16_t aid);
|
||||
|
||||
typedef struct {
|
||||
char *ssid; /**< SSID of AP */
|
||||
uint8_t *bssid; /**< MAC address of AP */
|
||||
uint8_t channel; /**< channel, scan the specific channel */
|
||||
bool show_hidden; /**< enable to scan AP whose SSID is hidden */
|
||||
bool show_hidden; /**< enable to scan AP whose SSID is hidden */
|
||||
} wifi_scan_config_t;
|
||||
|
||||
/**
|
||||
* @brief Scan all available APs.
|
||||
*
|
||||
* @attention If this API is called, the found APs are stored in WiFi driver dynamic allocated memory and the
|
||||
* will be freed in esp_wifi_get_ap_list, so generally, call esp_wifi_get_ap_list to cause
|
||||
* the memory to be freed once the scan is done
|
||||
*
|
||||
* @param struct scan_config *config : configuration of scanning
|
||||
* @param bool block : if block is true, this API will block the caller until the scan is done, otherwise
|
||||
* it will return immediately
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_wifi_scan_start(wifi_scan_config_t *conf, bool block);
|
||||
|
||||
/**
|
||||
* @brief Stop the scan in process
|
||||
*
|
||||
* @param null
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_wifi_scan_stop(void);
|
||||
|
||||
/**
|
||||
* @brief Get number of APs found in last scan
|
||||
*
|
||||
* @param uint16_t *number : store number of APIs found in last scan
|
||||
*
|
||||
* @attention This API can only be called when the scan is completed, otherwise it may get wrong value
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_wifi_get_ap_num(uint16_t *number);
|
||||
|
||||
typedef struct {
|
||||
@ -144,58 +337,226 @@ typedef struct {
|
||||
uint8_t ssid[32]; /**< SSID of AP */
|
||||
uint8_t primary; /**< channel of AP */
|
||||
wifi_second_chan_t second; /**< second channel of AP */
|
||||
signed char rssi; /**< signal strength of AP */
|
||||
int8_t rssi; /**< signal strength of AP */
|
||||
wifi_auth_mode_t authmode; /**< authmode of AP */
|
||||
}wifi_ap_list_t;
|
||||
} wifi_ap_list_t;
|
||||
|
||||
/**
|
||||
* @brief Get AP list found in last scan
|
||||
*
|
||||
* @param uint16_t *number : as input param, it stores max AP number ap_list can hold, as output param, it store
|
||||
the actual AP number this API returns
|
||||
* @param wifi_ap_list_t *ap_list : a list to hold the found APs
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_wifi_get_ap_list(uint16_t *number, wifi_ap_list_t *ap_list);
|
||||
|
||||
typedef enum {
|
||||
WIFI_PS_NONE,
|
||||
WIFI_PS_MODEM,
|
||||
WIFI_PS_LIGHT,
|
||||
WIFI_PS_MAC,
|
||||
WIFI_PS_NONE, /**< No power save */
|
||||
WIFI_PS_MODEM, /**< Modem power save */
|
||||
WIFI_PS_LIGHT, /**< Light power save */
|
||||
WIFI_PS_MAC, /**< MAC power save */
|
||||
} wifi_ps_type_t;
|
||||
|
||||
/**
|
||||
* @brief Set current power save type
|
||||
*
|
||||
* @param wifi_ps_type_t type : power save type
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_wifi_set_ps(wifi_ps_type_t type);
|
||||
|
||||
/**
|
||||
* @brief Get current power save type
|
||||
*
|
||||
* @param wifi_ps_type_t *type : store current power save type
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_wifi_get_ps(wifi_ps_type_t *type);
|
||||
|
||||
#define WIFI_PROTOCOL_11B 1
|
||||
#define WIFI_PROTOCOL_11G 2
|
||||
#define WIFI_PROTOCOL_11N 4
|
||||
|
||||
esp_err_t esp_wifi_set_protocol(wifi_interface_t ifx, uint8_t protocol);
|
||||
/**
|
||||
* @brief Set protocol type of specified interface
|
||||
* The default protocol is (WIFI_PROTOCOL_11B|WIFI_PROTOCOL_11G|WIFI_PROTOCOL_11N)
|
||||
*
|
||||
* @attention Currently we only support 802.11b or 802.11bg or 802.11bgn mode
|
||||
*
|
||||
* @param wifi_interface_t ifx : interfaces
|
||||
* @param uint8_t protocol : WiFi protocol bitmap
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_wifi_set_protocol(wifi_interface_t ifx, uint8_t protocol_bitmap);
|
||||
|
||||
esp_err_t esp_wifi_get_protocol(wifi_interface_t ifx, uint8_t *protocol);
|
||||
/**
|
||||
* @brief Get the current protocol bitmap of specified ifx
|
||||
*
|
||||
* @param wifi_interface_t ifx : interfaces
|
||||
* @param uint8_t protocol : store current WiFi protocol bitmap of interface ifx
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_wifi_get_protocol(wifi_interface_t ifx, uint8_t *protocol_bitmap);
|
||||
|
||||
typedef enum {
|
||||
WIFI_BW_HT20 = 0,
|
||||
WIFI_BW_HT40,
|
||||
WIFI_BW_HT20 = 0, /* Bandwidth is HT20 */
|
||||
WIFI_BW_HT40, /* Bandwidth is HT40 */
|
||||
} wifi_bandwidth_t;
|
||||
|
||||
/**
|
||||
* @brief Set the bandwidth of ESP32 specified interface
|
||||
*
|
||||
* @attention 1. API return false if try to configure a interface that is not enable
|
||||
* @attention 2. WIFI_BW_HT40 is supported only when the interface support 11N
|
||||
*
|
||||
* @param wifi_interface_t ifx : interface to be configured
|
||||
* @param wifi_bandwidth_t bw : bandwidth
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_wifi_set_bandwidth(wifi_interface_t ifx, wifi_bandwidth_t bw);
|
||||
|
||||
/**
|
||||
* @brief Get the bandwidth of ESP32 specified interface
|
||||
*
|
||||
* @attention 1. API return false if try to get a interface that is not enable
|
||||
*
|
||||
* @param wifi_interface_t ifx : interface to be configured
|
||||
* @param wifi_bandwidth_t *bw : store bandwidth of interface ifx
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_wifi_get_bandwidth(wifi_interface_t ifx, wifi_bandwidth_t *bw);
|
||||
|
||||
/**
|
||||
* @brief Set primary/second channel of ESP32
|
||||
*
|
||||
* @attention 1. This is a special API for sniffer
|
||||
*
|
||||
* @param uint8_t primary : for HT20, primary is the channel number, for HT40, primary is the primary channel
|
||||
* @param wifi_second_chan_t second : for HT20, second is ignored, for HT40, second is the second channel
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_wifi_set_channel(uint8_t primary, wifi_second_chan_t second);
|
||||
|
||||
/**
|
||||
* @brief Get the primary/second channel of ESP32
|
||||
*
|
||||
* @attention 1. API return false if try to get a interface that is not enable
|
||||
*
|
||||
* @param uint8_t *primary : store current primary channel
|
||||
* @param wifi_second_chan_t *second : store current second channel
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_wifi_get_channel(uint8_t *primary, wifi_second_chan_t *second);
|
||||
|
||||
/**
|
||||
* @brief Set country code
|
||||
* The default value is WIFI_COUNTRY_CN
|
||||
*
|
||||
* @param wifi_country_t country : country type
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_wifi_set_country(wifi_country_t country);
|
||||
|
||||
/**
|
||||
* @brief Get country code
|
||||
*
|
||||
* @param wifi_country_t country : store current country
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_wifi_get_country(wifi_country_t *country);
|
||||
|
||||
/**
|
||||
* @brief Set MAC address of the ESP32 WiFi station or the soft-AP interface.
|
||||
*
|
||||
* @attention 1. This API can only be called when the interface is disabled
|
||||
* @attention 2. ESP32 soft-AP and station have different MAC addresses, do not set them to be the same.
|
||||
* - The bit0 of the first byte of ESP32 MAC address can not be 1. For example, the MAC address
|
||||
* can set to be "1a:XX:XX:XX:XX:XX", but can not be "15:XX:XX:XX:XX:XX".
|
||||
*
|
||||
* @param wifi_interface_t ifx : interface
|
||||
* @param uint8 mac[6]: the MAC address.
|
||||
*
|
||||
* @return true : succeed
|
||||
* @return false : fail
|
||||
*/
|
||||
esp_err_t esp_wifi_set_mac(wifi_interface_t ifx, uint8_t mac[6]);
|
||||
|
||||
/**
|
||||
* @brief Get mac of specified interface
|
||||
*
|
||||
* @param uint8_t mac[6] : store mac of this interface ifx
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_wifi_get_mac(wifi_interface_t ifx, uint8_t mac[6]);
|
||||
|
||||
/**
|
||||
* @brief The RX callback function in the promiscuous mode.
|
||||
*
|
||||
* Each time a packet is received, the callback function will be called.
|
||||
*
|
||||
* @param void *buf : the data received
|
||||
* @param uint16_t len : data length
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
typedef void (* wifi_promiscuous_cb_t)(void *buf, uint16_t len);
|
||||
|
||||
/**
|
||||
* @brief Register the RX callback function in the promiscuous mode.
|
||||
*
|
||||
* Each time a packet is received, the registered callback function will be called.
|
||||
*
|
||||
* @param wifi_promiscuous_cb_t cb : callback
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_wifi_set_promiscuous_rx_cb(wifi_promiscuous_cb_t cb);
|
||||
|
||||
/**
|
||||
* @brief Enable the promiscuous mode.
|
||||
*
|
||||
* @param uint8 promiscuous : 0 - disable / 1 - enable
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_wifi_set_promiscuous(uint8_t enable);
|
||||
|
||||
/**
|
||||
* @brief Get the promiscuous mode.
|
||||
*
|
||||
* @param uint8 *enable : store the current status of promiscuous mode
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_wifi_get_promiscuous(uint8_t *enable);
|
||||
|
||||
typedef struct {
|
||||
@ -206,7 +567,7 @@ typedef struct {
|
||||
wifi_auth_mode_t authmode; /**< Auth mode of ESP32 soft-AP. Do not support AUTH_WEP in soft-AP mode */
|
||||
uint8_t ssid_hidden; /**< Broadcast SSID or not, default 0, broadcast the SSID */
|
||||
uint8_t max_connection; /**< Max number of stations allowed to connect in, default 4, max 4 */
|
||||
uint16_t beacon_interval; /**< Beacon interval, 100 ~ 60000 ms, default 100 */
|
||||
uint16_t beacon_interval; /**< Beacon interval, 100 ~ 60000 ms, default 100 ms */
|
||||
} wifi_ap_config_t;
|
||||
|
||||
typedef struct {
|
||||
@ -217,12 +578,35 @@ typedef struct {
|
||||
} wifi_sta_config_t;
|
||||
|
||||
typedef union {
|
||||
wifi_ap_config_t ap;
|
||||
wifi_sta_config_t sta;
|
||||
wifi_ap_config_t ap; /**< configuration of AP */
|
||||
wifi_sta_config_t sta; /**< configuration of STA */
|
||||
} wifi_config_t;
|
||||
|
||||
/**
|
||||
* @brief Set the configuration of the ESP32 STA or AP
|
||||
*
|
||||
* @attention 1. This API can be called only when specified interface is enabled, otherwise, API fail
|
||||
* @attention 2. For station configuration, bssid_set needs to be 0; and it needs to be 1 only when users need to check the MAC address of the AP.
|
||||
* @attention 3. ESP32 is limited to only one channel, so when in the soft-AP+station mode, the soft-AP will adjust its channel automatically to be the same as
|
||||
* the channel of the ESP32 station.
|
||||
*
|
||||
* @param wifi_interface_t ifx : interface
|
||||
* @param wifi_config_t *conf : station or soft-AP configuration
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_wifi_set_config(wifi_interface_t ifx, wifi_config_t *conf);
|
||||
|
||||
/**
|
||||
* @brief Get configuration of specified interface
|
||||
*
|
||||
* @param wifi_interface_t ifx : interface
|
||||
* @param wifi_config_t *conf : station or soft-AP configuration
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_wifi_get_config(wifi_interface_t ifx, wifi_config_t *conf);
|
||||
|
||||
struct station_info {
|
||||
@ -230,23 +614,79 @@ struct station_info {
|
||||
uint8_t bssid[6];
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Get STAs associated with soft-AP
|
||||
*
|
||||
* @attention SSC only API
|
||||
*
|
||||
* @param struct station_info **station : station list
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_wifi_get_station_list(struct station_info **station);
|
||||
|
||||
esp_err_t esp_wifi_free_station_list(void);
|
||||
|
||||
typedef enum {
|
||||
WIFI_STORAGE_RAM,
|
||||
WIFI_STORAGE_FLASH,
|
||||
WIFI_STORAGE_FLASH, /**< all configuration will strore in both memory and flash */
|
||||
WIFI_STORAGE_RAM, /**< all configuration will only store in the memory */
|
||||
} wifi_storage_t;
|
||||
|
||||
/**
|
||||
* @brief Set the WiFi API configuration storage type
|
||||
*
|
||||
* @attention 1. The default value is WIFI_STORAGE_FLASH
|
||||
*
|
||||
* @param wifi_storage_t storage : storage type
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_wifi_set_storage(wifi_storage_t storage);
|
||||
|
||||
typedef esp_err_t (*wifi_rxcb_t)(void *buffer, uint16_t len, void* eb);
|
||||
/**
|
||||
* @brief The WiFi RX callback function
|
||||
*
|
||||
* Each time the WiFi need to forward the packets to high layer, the callback function will be called
|
||||
*
|
||||
*/
|
||||
typedef esp_err_t (*wifi_rxcb_t)(void *buffer, uint16_t len, void *eb);
|
||||
|
||||
/**
|
||||
* @brief Set the WiFi RX callback
|
||||
*
|
||||
* @attention 1. Currently we support only one RX callback for each interface
|
||||
*
|
||||
* @param wifi_interface_t ifx : interface
|
||||
* @param wifi_rxcb_t fn : WiFi RX callback
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_wifi_reg_rxcb(wifi_interface_t ifx, wifi_rxcb_t fn);
|
||||
|
||||
/**
|
||||
* @brief Set auto connect
|
||||
* The default value is true
|
||||
*
|
||||
* @attention 1.
|
||||
*
|
||||
* @param bool en : true - enable auto connect / false - disable auto connect
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_wifi_set_auto_connect(bool en);
|
||||
|
||||
/**
|
||||
* @brief Get the auto connect flag
|
||||
*
|
||||
* @param bool *en : store current auto connect configuration
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_wifi_get_auto_connect(bool *en);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -11,6 +11,7 @@
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _ROM_AES_H_
|
||||
#define _ROM_AES_H_
|
||||
|
||||
@ -21,6 +22,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//TODO, add comment for aes apis
|
||||
enum AES_BITS {
|
||||
AES128,
|
||||
AES192,
|
||||
@ -32,8 +34,8 @@ void ets_aes_enable(void);
|
||||
void ets_aes_disable(void);
|
||||
|
||||
void ets_aes_set_endian(bool key_word_swap, bool key_byte_swap,
|
||||
bool in_word_swap, bool in_byte_swap,
|
||||
bool out_word_swap, bool out_byte_swap);
|
||||
bool in_word_swap, bool in_byte_swap,
|
||||
bool out_word_swap, bool out_byte_swap);
|
||||
|
||||
bool ets_aes_setkey_enc(const uint8_t *key, enum AES_BITS bits);
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _ROM_BIGINT_H_
|
||||
#define _ROM_BIGINT_H_
|
||||
|
||||
@ -21,6 +22,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//TODO: add comment here
|
||||
void ets_bigint_enable(void);
|
||||
|
||||
void ets_bigint_disable(void);
|
||||
|
@ -11,6 +11,7 @@
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _ROM_CACHE_H_
|
||||
#define _ROM_CACHE_H_
|
||||
|
||||
@ -18,50 +19,126 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
//===========================================
|
||||
// function : cache_init
|
||||
// description: initialise cache mmu, mark all entries as invalid.
|
||||
// conditions:
|
||||
// Call Cache_Read_Disable() before calling this function.
|
||||
// inputs:
|
||||
// cpu_no is CPU number,0(PRO CPU) or 1(APP CPU),
|
||||
// output: NONE
|
||||
//===========================================
|
||||
/** \defgroup uart_apis, uart configuration and communication related apis
|
||||
* @brief uart apis
|
||||
*/
|
||||
|
||||
/** @addtogroup uart_apis
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Initialise cache mmu, mark all entries as invalid.
|
||||
* Please do not call this function in your SDK application.
|
||||
*
|
||||
* @param int cpu_no : 0 for PRO cpu, 1 for APP cpu.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void mmu_init(int cpu_no);
|
||||
|
||||
//===========================================
|
||||
// function : cache_flash_mmu_set
|
||||
// description: Configure MMU to cache a flash region.
|
||||
// conditions:
|
||||
// Call this function to configure the flash cache before enabling it.
|
||||
// Check return value to verify MMU was set correctly.
|
||||
// inputs:
|
||||
// cpu_no is CPU number,0(PRO CPU) or 1(APP CPU),
|
||||
// pid is process identifier. Range 0~7
|
||||
// vaddr is "virtual" address in CPU address space. Can be IRam0, IRam1, IRom0 and DRom0 memory address.
|
||||
// Should be aligned by psize
|
||||
// paddr is "physical" address in flash controller's address space.
|
||||
// ie for 16M flash the range is 0x000000~0xFFFFFF. Should be aligned by psize
|
||||
// psize is page size of flash, in kilobytes. Can be 64, 32, 16.
|
||||
// num is number of pages to be set, valid range 0 ~ (flash size)/(page size)
|
||||
// output: error status
|
||||
// 0 : mmu set success
|
||||
// 1 : vaddr or paddr is not aligned
|
||||
// 2 : pid error
|
||||
// 3 : psize error
|
||||
// 4 : mmu table to be written is out of range
|
||||
// 5 : vaddr is out of range
|
||||
//===========================================
|
||||
/**
|
||||
* @brief Set Flash-Cache mmu mapping.
|
||||
* Please do not call this function in your SDK application.
|
||||
*
|
||||
* @param int cpu_no : CPU number, 0 for PRO cpu, 1 for APP cpu.
|
||||
*
|
||||
* @param int pod : process identifier. Range 0~7.
|
||||
*
|
||||
* @param unsigned int vaddr : virtual address in CPU address space.
|
||||
* Can be IRam0, IRam1, IRom0 and DRom0 memory address.
|
||||
* Should be aligned by psize.
|
||||
*
|
||||
* @param unsigned int paddr : physical address in Flash.
|
||||
* Should be aligned by psize.
|
||||
*
|
||||
* @param int psize : page size of flash, in kilobytes. Should be 64 here.
|
||||
*
|
||||
* @param int num : pages to be set.
|
||||
*
|
||||
* @return unsigned int: error status
|
||||
* 0 : mmu set success
|
||||
* 1 : vaddr or paddr is not aligned
|
||||
* 2 : pid error
|
||||
* 3 : psize error
|
||||
* 4 : mmu table to be written is out of range
|
||||
* 5 : vaddr is out of range
|
||||
*/
|
||||
unsigned int cache_flash_mmu_set(int cpu_no, int pid, unsigned int vaddr, unsigned int paddr, int psize, int num);
|
||||
|
||||
unsigned int cache_sram_mmu_set(int cpu_no, int pid,unsigned int vaddr, unsigned int paddr, int psize, int num);
|
||||
/**
|
||||
* @brief Set Ext-SRAM-Cache mmu mapping.
|
||||
* Please do not call this function in your SDK application.
|
||||
*
|
||||
* @param int cpu_no : CPU number, 0 for PRO cpu, 1 for APP cpu.
|
||||
*
|
||||
* @param int pod : process identifier. Range 0~7.
|
||||
*
|
||||
* @param unsigned int vaddr : virtual address in CPU address space.
|
||||
* Can be IRam0, IRam1, IRom0 and DRom0 memory address.
|
||||
* Should be aligned by psize.
|
||||
*
|
||||
* @param unsigned int paddr : physical address in Ext-SRAM.
|
||||
* Should be aligned by psize.
|
||||
*
|
||||
* @param int psize : page size of flash, in kilobytes. Should be 32 here.
|
||||
*
|
||||
* @param int num : pages to be set.
|
||||
*
|
||||
* @return unsigned int: error status
|
||||
* 0 : mmu set success
|
||||
* 1 : vaddr or paddr is not aligned
|
||||
* 2 : pid error
|
||||
* 3 : psize error
|
||||
* 4 : mmu table to be written is out of range
|
||||
* 5 : vaddr is out of range
|
||||
*/
|
||||
unsigned int cache_sram_mmu_set(int cpu_no, int pid, unsigned int vaddr, unsigned int paddr, int psize, int num);
|
||||
|
||||
/**
|
||||
* @brief Initialise cache access for the cpu.
|
||||
* Please do not call this function in your SDK application.
|
||||
*
|
||||
* @param int cpu_no : 0 for PRO cpu, 1 for APP cpu.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void Cache_Read_Init(int cpu_no);
|
||||
|
||||
/**
|
||||
* @brief Flush the cache value for the cpu.
|
||||
* Please do not call this function in your SDK application.
|
||||
*
|
||||
* @param int cpu_no : 0 for PRO cpu, 1 for APP cpu.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void Cache_Flush(int cpu_no);
|
||||
|
||||
/**
|
||||
* @brief Disable Cache access for the cpu.
|
||||
* Please do not call this function in your SDK application.
|
||||
*
|
||||
* @param int cpu_no : 0 for PRO cpu, 1 for APP cpu.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void Cache_Read_Disable(int cpu_no);
|
||||
|
||||
/**
|
||||
* @brief Enable Cache access for the cpu.
|
||||
* Please do not call this function in your SDK application.
|
||||
*
|
||||
* @param int cpu_no : 0 for PRO cpu, 1 for APP cpu.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void Cache_Read_Enable(int cpu_no);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -11,20 +11,113 @@
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef ROM_CRC_H
|
||||
#define ROM_CRC_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup uart_apis, uart configuration and communication related apis
|
||||
* @brief uart apis
|
||||
*/
|
||||
|
||||
/** @addtogroup uart_apis
|
||||
* @{
|
||||
*/
|
||||
|
||||
|
||||
/* Standard CRC8/16/32 algorithms. */
|
||||
uint32_t crc32_le(uint32_t crc, uint8_t const * buf, uint32_t len);
|
||||
uint32_t crc32_be(uint32_t crc, uint8_t const * buf, uint32_t len);
|
||||
uint16_t crc16_le(uint16_t crc, uint8_t const * buf, uint32_t len);
|
||||
uint16_t crc16_be(uint16_t crc, uint8_t const * buf, uint32_t len);
|
||||
uint8_t crc8_le(uint8_t crc, uint8_t const * buf, uint32_t len);
|
||||
uint8_t crc8_be(uint8_t crc, uint8_t const * buf, uint32_t len);
|
||||
// CRC-8 x8+x2+x1+1 0x07
|
||||
// CRC16-CCITT x16+x12+x5+1 1021 ISO HDLC, ITU X.25, V.34/V.41/V.42, PPP-FCS
|
||||
// CRC32:
|
||||
//G(x) = x32 +x26 + x23 + x22 + x16 + x12 + x11 + x10 + x8 + x7 + x5 + x4 + x2 + x1 + 1
|
||||
//If your buf is not continuous, you can use the first result to be the second parameter.
|
||||
|
||||
/**
|
||||
* @brief Crc32 value that is in little endian.
|
||||
*
|
||||
* @param uint32_t crc : init crc value, use 0 at the first use.
|
||||
*
|
||||
* @param uint8_t const *buf : buffer to start calculate crc.
|
||||
*
|
||||
* @param uint32_t len : buffer length in byte.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
uint32_t crc32_le(uint32_t crc, uint8_t const *buf, uint32_t len);
|
||||
|
||||
/**
|
||||
* @brief Crc32 value that is in big endian.
|
||||
*
|
||||
* @param uint32_t crc : init crc value, use 0 at the first use.
|
||||
*
|
||||
* @param uint8_t const *buf : buffer to start calculate crc.
|
||||
*
|
||||
* @param uint32_t len : buffer length in byte.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
uint32_t crc32_be(uint32_t crc, uint8_t const *buf, uint32_t len);
|
||||
|
||||
/**
|
||||
* @brief Crc16 value that is in little endian.
|
||||
*
|
||||
* @param uint16_t crc : init crc value, use 0 at the first use.
|
||||
*
|
||||
* @param uint8_t const *buf : buffer to start calculate crc.
|
||||
*
|
||||
* @param uint32_t len : buffer length in byte.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
uint16_t crc16_le(uint16_t crc, uint8_t const *buf, uint32_t len);
|
||||
|
||||
/**
|
||||
* @brief Crc16 value that is in big endian.
|
||||
*
|
||||
* @param uint16_t crc : init crc value, use 0 at the first use.
|
||||
*
|
||||
* @param uint8_t const *buf : buffer to start calculate crc.
|
||||
*
|
||||
* @param uint32_t len : buffer length in byte.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
uint16_t crc16_be(uint16_t crc, uint8_t const *buf, uint32_t len);
|
||||
|
||||
/**
|
||||
* @brief Crc8 value that is in little endian.
|
||||
*
|
||||
* @param uint8_t crc : init crc value, use 0 at the first use.
|
||||
*
|
||||
* @param uint8_t const *buf : buffer to start calculate crc.
|
||||
*
|
||||
* @param uint32_t len : buffer length in byte.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
uint8_t crc8_le(uint8_t crc, uint8_t const *buf, uint32_t len);
|
||||
|
||||
/**
|
||||
* @brief Crc8 value that is in big endian.
|
||||
*
|
||||
* @param uint32_t crc : init crc value, use 0 at the first use.
|
||||
*
|
||||
* @param uint8_t const *buf : buffer to start calculate crc.
|
||||
*
|
||||
* @param uint32_t len : buffer length in byte.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
uint8_t crc8_be(uint8_t crc, uint8_t const *buf, uint32_t len);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -11,17 +11,100 @@
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _ROM_EFUSE_H_
|
||||
#define _ROM_EFUSE_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup efuse_APIs efuse APIs
|
||||
* @brief ESP32 efuse read/write APIs
|
||||
* @attention
|
||||
*
|
||||
*/
|
||||
|
||||
/** @addtogroup efuse_APIs
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Do a efuse read operation, to update the efuse value to efuse read registers.
|
||||
*
|
||||
* @param null
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
void ets_efuse_read_op(void);
|
||||
|
||||
/**
|
||||
* @brief Do a efuse write operation, to update efuse write registers to efuse, then you need call ets_efuse_read_op again.
|
||||
*
|
||||
* @param null
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
void ets_efuse_program_op(void);
|
||||
|
||||
/**
|
||||
* @brief Read 8M Analog Clock value(8 bit) in efuse, the analog clock will not change with temperature.
|
||||
* It can be used to test the external xtal frequency, do not touch this efuse field.
|
||||
*
|
||||
* @param null
|
||||
*
|
||||
* @return u32: 1 for 100KHZ, range is 0 to 255.
|
||||
*/
|
||||
uint32_t ets_efuse_get_8M_clock(void);
|
||||
|
||||
/**
|
||||
* @brief Read spi pad configuration, show gpio number of flash pad, includes 5 pads.
|
||||
*
|
||||
* @param null
|
||||
*
|
||||
* @return uint32_t: 0, invalid, flash pad decided by strapping
|
||||
* else, bit[5:0] spiclk, bit[11:6] spiq, bit[17:12] spid, bit[23:18] spics0, bit[29:24] spihd
|
||||
*/
|
||||
uint32_t ets_efuse_get_spiconfig(void);
|
||||
|
||||
#define EFUSE_SPICONFIG_RET_SPICLK_MASK 0x3f
|
||||
#define EFUSE_SPICONFIG_RET_SPICLK_SHIFT 0
|
||||
#define EFUSE_SPICONFIG_RET_SPICLK(ret) (((ret) >> EFUSE_SPICONFIG_RET_SPICLK_SHIFT) & EFUSE_SPICONFIG_RET_SPICLK_MASK)
|
||||
|
||||
#define EFUSE_SPICONFIG_RET_SPIQ_MASK 0x3f
|
||||
#define EFUSE_SPICONFIG_RET_SPIQ_SHIFT 6
|
||||
#define EFUSE_SPICONFIG_RET_SPIQ(ret) (((ret) >> EFUSE_SPICONFIG_RET_SPIQ_SHIFT) & EFUSE_SPICONFIG_RET_SPIQ_MASK)
|
||||
|
||||
#define EFUSE_SPICONFIG_RET_SPID_MASK 0x3f
|
||||
#define EFUSE_SPICONFIG_RET_SPID_SHIFT 12
|
||||
#define EFUSE_SPICONFIG_RET_SPID(ret) (((ret) >> EFUSE_SPICONFIG_RET_SPID_SHIFT) & EFUSE_SPICONFIG_RET_SPID_MASK)
|
||||
|
||||
#define EFUSE_SPICONFIG_RET_SPICS0_MASK 0x3f
|
||||
#define EFUSE_SPICONFIG_RET_SPICS0_SHIFT 18
|
||||
#define EFUSE_SPICONFIG_RET_SPICS0(ret) (((ret) >> EFUSE_SPICONFIG_RET_SPICS0_SHIFT) & EFUSE_SPICONFIG_RET_SPICS0_MASK)
|
||||
|
||||
|
||||
#define EFUSE_SPICONFIG_RET_SPIHD_MASK 0x3f
|
||||
#define EFUSE_SPICONFIG_RET_SPIHD_SHIFT 24
|
||||
#define EFUSE_SPICONFIG_RET_SPIHD(ret) (((ret) >> EFUSE_SPICONFIG_RET_SPIHD_SHIFT) & EFUSE_SPICONFIG_RET_SPIHD_MASK)
|
||||
|
||||
/**
|
||||
* @brief A crc8 algorithm used in efuse check.
|
||||
*
|
||||
* @param unsigned char const *p : Pointer to original data.
|
||||
*
|
||||
* @param unsigned int len : Data length in byte.
|
||||
*
|
||||
* @return unsigned char: Crc value.
|
||||
*/
|
||||
unsigned char esp_crc8(unsigned char const *p, unsigned int len);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -24,82 +24,242 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define ETS_DEBUG
|
||||
#define ETS_SERIAL_ENABLED() (1)
|
||||
/** \defgroup ets_sys_apis, ets system related apis
|
||||
* @brief ets system apis
|
||||
*/
|
||||
|
||||
/** @addtogroup ets_sys_apis
|
||||
* @{
|
||||
*/
|
||||
|
||||
/************************************************************************
|
||||
* NOTE
|
||||
* Many functions in this header files can't be run in FreeRTOS.
|
||||
* Please see the comment of the Functions.
|
||||
* There are also some functions that doesn't work on FreeRTOS
|
||||
* without listed in the header, such as:
|
||||
* xtos functions start with "_xtos_" in ld file.
|
||||
*
|
||||
***********************************************************************
|
||||
*/
|
||||
|
||||
/** \defgroup ets_apis, Espressif Task Scheduler related apis
|
||||
* @brief ets apis
|
||||
*/
|
||||
|
||||
/** @addtogroup ets_apis
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
ETS_OK = 0,
|
||||
ETS_FAILED = 1
|
||||
ETS_OK = 0, /**< return successful in ets*/
|
||||
ETS_FAILED = 1 /**< return failed in ets*/
|
||||
} ETS_STATUS;
|
||||
|
||||
typedef uint32_t ETSSignal;
|
||||
typedef uint32_t ETSParam;
|
||||
|
||||
typedef struct ETSEventTag ETSEvent;
|
||||
typedef struct ETSEventTag ETSEvent; /**< Event transmit/receive in ets*/
|
||||
|
||||
struct ETSEventTag {
|
||||
ETSSignal sig;
|
||||
ETSParam par;
|
||||
ETSSignal sig; /**< Event signal, in same task, different Event with different signal*/
|
||||
ETSParam par; /**< Event parameter, sometimes without usage, then will be set as 0*/
|
||||
};
|
||||
|
||||
typedef void (*ETSTask)(ETSEvent *e);
|
||||
|
||||
enum ETS_User_Priorities {
|
||||
/* task priorities... */
|
||||
TICK_TASK_A_PRIO = 2,
|
||||
KBD_TASK_PRIO = 5,
|
||||
MAX_ETS_USER_PRIO = 16,
|
||||
|
||||
/* ISR priorities... */
|
||||
MAX_ETS_USER_ISR_PRIO = 0xFF - 16
|
||||
};
|
||||
|
||||
/* ETS interrupt entry and exit */
|
||||
/* actually we don't need the following 2 macros any more since we won't exit
|
||||
* isr until it is finised, more over, we don't do nest interrupt
|
||||
*/
|
||||
typedef void (*ETSTask)(ETSEvent *e); /**< Type of the Task processer*/
|
||||
typedef void (* ets_idle_cb_t)(void *arg); /**< Type of the system idle callback*/
|
||||
|
||||
/**
|
||||
* @brief Start the Espressif Task Scheduler, which is an infinit loop. Please do not add code after it.
|
||||
*
|
||||
* @param none
|
||||
*
|
||||
* @return none
|
||||
*/
|
||||
void ets_run(void);
|
||||
|
||||
/**
|
||||
* @brief Set the Idle callback, when Tasks are processed, will call the callback before CPU goto sleep.
|
||||
*
|
||||
* @param ets_idle_cb_t func : The callback function.
|
||||
*
|
||||
* @param void *arg : Argument of the callback.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void ets_set_idle_cb(ets_idle_cb_t func, void *arg);
|
||||
|
||||
/**
|
||||
* @brief Init a task with processer, priority, queue to receive Event, queue length.
|
||||
*
|
||||
* @param ETSTask task : The task processer.
|
||||
*
|
||||
* @param uint8_t prio : Task priority, 0-31, bigger num with high priority, one priority with one task.
|
||||
*
|
||||
* @param ETSEvent *queue : Queue belongs to the task, task always receives Events, Queue is circular used.
|
||||
*
|
||||
* @param uint8_t qlen : Queue length.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void ets_task(ETSTask task, uint8_t prio, ETSEvent *queue, uint8_t qlen);
|
||||
|
||||
ETS_STATUS ets_post(uint8_t prio, ETSSignal sig, ETSParam par);
|
||||
/**
|
||||
* @brief Post an event to an Task.
|
||||
*
|
||||
* @param uint8_t prio : Priority of the Task.
|
||||
*
|
||||
* @param ETSSignal sig : Event signal.
|
||||
*
|
||||
* @param ETSParam par : Event parameter
|
||||
*
|
||||
* @return ETS_OK : post successful
|
||||
* @return ETS_FAILED : post failed
|
||||
*/
|
||||
ETS_STATUS ets_post(uint8_t prio, ETSSignal sig, ETSParam par);
|
||||
|
||||
/*
|
||||
* now things become complicated, print could be directed to uart and/or SDIO
|
||||
*/
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** \defgroup ets_boot_apis, Boot routing related apis
|
||||
* @brief ets boot apis
|
||||
*/
|
||||
|
||||
/** @addtogroup ets_apis
|
||||
* @{
|
||||
*/
|
||||
|
||||
extern const char *const exc_cause_table[40]; ///**< excption cause that defined by the core.*/
|
||||
|
||||
/**
|
||||
* @brief Set Pro cpu Entry code, code can be called in PRO CPU when booting is not completed.
|
||||
* When Pro CPU booting is completed, Pro CPU will call the Entry code if not NULL.
|
||||
*
|
||||
* @param uint32_t start : the PRO Entry code address value in uint32_t
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void ets_set_user_start(uint32_t start);
|
||||
|
||||
/**
|
||||
* @brief Set Pro cpu Startup code, code can be called when booting is not completed, or in Entry code.
|
||||
* When Entry code completed, CPU will call the Startup code if not NULL, else call ets_run.
|
||||
*
|
||||
* @param uint32_t callback : the Startup code address value in uint32_t
|
||||
*
|
||||
* @return None : post successful
|
||||
*/
|
||||
void ets_set_startup_callback(uint32_t callback);
|
||||
|
||||
/**
|
||||
* @brief Set App cpu Entry code, code can be called in PRO CPU.
|
||||
* When APP booting is completed, APP CPU will call the Entry code if not NULL.
|
||||
*
|
||||
* @param uint32_t start : the APP Entry code address value in uint32_t, stored in register APPCPU_CTRL_REG_D.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void ets_set_appcpu_boot_addr(uint32_t start);
|
||||
|
||||
/**
|
||||
* @brief unpack the image in flash to iram and dram, no using cache.
|
||||
*
|
||||
* @param uint32_t pos : Flash physical address.
|
||||
*
|
||||
* @param uint32_t *entry_addr: the pointer of an variable that can store Entry code address.
|
||||
*
|
||||
* @param bool jump : Jump into the code in the function or not.
|
||||
*
|
||||
* @param bool config : Config the flash when unpacking the image, config should be done only once.
|
||||
*
|
||||
* @return ETS_OK : unpack successful
|
||||
* @return ETS_FAILED : unpack failed
|
||||
*/
|
||||
ETS_STATUS ets_unpack_flash_code_legacy(uint32_t pos, uint32_t *entry_addr, bool jump, bool config);
|
||||
|
||||
/**
|
||||
* @brief unpack the image in flash to iram and dram, using cache, maybe decrypting.
|
||||
*
|
||||
* @param uint32_t pos : Flash physical address.
|
||||
*
|
||||
* @param uint32_t *entry_addr: the pointer of an variable that can store Entry code address.
|
||||
*
|
||||
* @param bool jump : Jump into the code in the function or not.
|
||||
*
|
||||
* @param bool sb_need_check : Do security boot check or not.
|
||||
*
|
||||
* @param bool config : Config the flash when unpacking the image, config should be done only once.
|
||||
*
|
||||
* @return ETS_OK : unpack successful
|
||||
* @return ETS_FAILED : unpack failed
|
||||
*/
|
||||
ETS_STATUS ets_unpack_flash_code(uint32_t pos, uint32_t *entry_addr, bool jump, bool sb_need_check, bool config);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** \defgroup ets_printf_apis, ets_printf related apis used in ets
|
||||
* @brief ets printf apis
|
||||
*/
|
||||
|
||||
/** @addtogroup ets_printf_apis
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Printf the strings to uart or other devices, similar with printf, simple than printf.
|
||||
* Can not print float point data format, or longlong data format.
|
||||
* So we maybe only use this in ROM.
|
||||
*
|
||||
* @param const char *fmt : See printf.
|
||||
*
|
||||
* @param ... : See printf.
|
||||
*
|
||||
* @return int : the length printed to the output device.
|
||||
*/
|
||||
int ets_printf(const char *fmt, ...);
|
||||
|
||||
/* by default it's UART, just install_uart_printf, set putc1 to NULL to disable */
|
||||
/**
|
||||
* @brief Output a char to uart, which uart to output(which is in uart module in ROM) is not in scope of the function.
|
||||
* Can not print float point data format, or longlong data format
|
||||
*
|
||||
* @param char c : char to output.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void ets_write_char_uart(char c);
|
||||
|
||||
/**
|
||||
* @brief Ets_printf have two output functions: putc1 and putc2, both of which will be called if need ouput.
|
||||
* To install putc1, which is defaulted installed as ets_write_char_uart in none silent boot mode, as NULL in silent mode.
|
||||
*
|
||||
* @param void (*)(char) p: Output function to install.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void ets_install_putc1(void (*p)(char c));
|
||||
void ets_install_uart_printf(void);
|
||||
|
||||
/* no need to install, call directly */
|
||||
int ets_uart_printf(const char *fmt, ...);
|
||||
|
||||
/* usually we don't need to call this, unless we want to disable SDIO print */
|
||||
/**
|
||||
* @brief Ets_printf have two output functions: putc1 and putc2, both of which will be called if need ouput.
|
||||
* To install putc2, which is defaulted installed as NULL.
|
||||
*
|
||||
* @param void (*)(char) p: Output function to install.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void ets_install_putc2(void (*p)(char c));
|
||||
/* @prepare_buf: allocate buffer for printf internal writting
|
||||
* @putc: just set to NULL, let printf write to to buffer, unless if you want more fancy stuff
|
||||
* @post_printf: will be called every time printf finish write buffer
|
||||
*
|
||||
* main idea of external printf is re-directing content to an external buffer.
|
||||
* e.g. sip module allocates an event buffer in prepare_buf() and send the event to host in post_printf()
|
||||
* moreover, you can check printf_buf_remain_len in post_printf(), send the event to host till buf is
|
||||
* about to full.
|
||||
*
|
||||
* TBD: Another approach is sending printf parameter to host and let host to decode, which could save some bytes.
|
||||
*/
|
||||
void ets_install_external_printf(void (*prepare_buf)(char ** bufptr, uint16_t *buflen, uint32_t *cookie),
|
||||
void (*putc)(char c),
|
||||
void (*post_printf)(uint32_t cookie));
|
||||
|
||||
uint16_t est_get_printf_buf_remain_len(void);
|
||||
void est_reset_printf_buf_len(void);
|
||||
|
||||
/* external (SDIO) printf only, still need to install*/
|
||||
int ets_external_printf(const char *fmt, ...);
|
||||
|
||||
/**
|
||||
* @brief Install putc1 as ets_write_char_uart.
|
||||
* In silent boot mode(to void interfere the UART attached MCU), we can call this function, after booting ok.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void ets_install_uart_printf(void);
|
||||
|
||||
#define ETS_PRINTF(...) ets_printf(...)
|
||||
|
||||
@ -110,82 +270,251 @@ int ets_external_printf(const char *fmt, ...);
|
||||
} \
|
||||
} while (0);
|
||||
|
||||
/* memory and string support */
|
||||
int8_t ets_char2xdigit(char ch);
|
||||
uint8_t * ets_str2macaddr(uint8_t *macaddr, char *str);
|
||||
void ets_getc(char *c);
|
||||
void ets_putc(char c);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/* timer related */
|
||||
typedef uint32_t ETSHandle;
|
||||
typedef void ETSTimerFunc(void *timer_arg);
|
||||
/** \defgroup ets_timer_apis, ets_timer related apis used in ets
|
||||
* @brief ets timer apis
|
||||
*/
|
||||
|
||||
/** @addtogroup ets_timer_apis
|
||||
* @{
|
||||
*/
|
||||
typedef void ETSTimerFunc(void *timer_arg);/**< timer handler*/
|
||||
|
||||
typedef struct _ETSTIMER_ {
|
||||
struct _ETSTIMER_ *timer_next;
|
||||
uint32_t timer_expire;
|
||||
uint32_t timer_period;
|
||||
ETSTimerFunc *timer_func;
|
||||
void *timer_arg;
|
||||
struct _ETSTIMER_ *timer_next; /**< timer linker*/
|
||||
uint32_t timer_expire; /**< abstruct time when timer expire*/
|
||||
uint32_t timer_period; /**< timer period, 0 means timer is not periodic repeated*/
|
||||
ETSTimerFunc *timer_func; /**< timer handler*/
|
||||
void *timer_arg; /**< timer handler argument*/
|
||||
} ETSTimer;
|
||||
|
||||
/**
|
||||
* @brief Init ets timer, this timer range is 640 us to 429496 ms
|
||||
* In FreeRTOS, please call FreeRTOS apis, never call this api.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void ets_timer_init(void);
|
||||
|
||||
/**
|
||||
* @brief Arm an ets timer, this timer range is 640 us to 429496 ms.
|
||||
* In FreeRTOS, please call FreeRTOS apis, never call this api.
|
||||
*
|
||||
* @param ETSTimer *timer : Timer struct pointer.
|
||||
*
|
||||
* @param uint32_t tmout : Timer value in ms, range is 1 to 429496.
|
||||
*
|
||||
* @param bool repeat : Timer is periodic repeated.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void ets_timer_arm(ETSTimer *timer, uint32_t tmout, bool repeat);
|
||||
|
||||
/**
|
||||
* @brief Arm an ets timer, this timer range is 640 us to 429496 ms.
|
||||
* In FreeRTOS, please call FreeRTOS apis, never call this api.
|
||||
*
|
||||
* @param ETSTimer *timer : Timer struct pointer.
|
||||
*
|
||||
* @param uint32_t tmout : Timer value in us, range is 1 to 429496729.
|
||||
*
|
||||
* @param bool repeat : Timer is periodic repeated.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void ets_timer_arm_us(ETSTimer *ptimer, uint32_t us, bool repeat);
|
||||
|
||||
/**
|
||||
* @brief Disarm an ets timer.
|
||||
* In FreeRTOS, please call FreeRTOS apis, never call this api.
|
||||
*
|
||||
* @param ETSTimer *timer : Timer struct pointer.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void ets_timer_disarm(ETSTimer *timer);
|
||||
void ets_timer_done(ETSTimer *ptimer);
|
||||
|
||||
/**
|
||||
* @brief Set timer callback and argument.
|
||||
* In FreeRTOS, please call FreeRTOS apis, never call this api.
|
||||
*
|
||||
* @param ETSTimer *timer : Timer struct pointer.
|
||||
*
|
||||
* @param ETSTimerFunc *pfunction : Timer callback.
|
||||
*
|
||||
* @param void *parg : Timer callback argument.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void ets_timer_setfn(ETSTimer *ptimer, ETSTimerFunc *pfunction, void *parg);
|
||||
|
||||
/* watchdog related */
|
||||
typedef enum {
|
||||
WDT_NONE = -1,
|
||||
WDT_DISABLED = 0,
|
||||
WDT_CONTROL_RESET = 1,
|
||||
WDT_CONTROL_INTR = 2, /* usually we use this mode? */
|
||||
WDT_CONTROL_EXTERNAL_FEED = 3,
|
||||
WDT_TESET_OVERFLOW = 4, // intend to make watchdog overflow to test
|
||||
} WDT_MODE;
|
||||
/**
|
||||
* @brief Unset timer callback and argument to NULL.
|
||||
* In FreeRTOS, please call FreeRTOS apis, never call this api.
|
||||
*
|
||||
* @param ETSTimer *timer : Timer struct pointer.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void ets_timer_done(ETSTimer *ptimer);
|
||||
|
||||
typedef enum{
|
||||
WDT_INTERVAL_THREE_SEC = 3,
|
||||
WDT_INTERVAL_SIX_SEC = 6,
|
||||
WDT_INTERVAL_TWELVE_SEC = 12,
|
||||
} WDT_INTERVAL_TIME;
|
||||
/**
|
||||
* @brief CPU do while loop for some time.
|
||||
* In FreeRTOS task, please call FreeRTOS apis.
|
||||
*
|
||||
* @param uint32_t us : Delay time in us.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void ets_delay_us(uint32_t us);
|
||||
|
||||
void ets_wdt_init(void);
|
||||
WDT_MODE ets_wdt_get_mode(void);
|
||||
void ets_wdt_enable(WDT_MODE mode, WDT_INTERVAL_TIME feed_interval,
|
||||
WDT_INTERVAL_TIME expire_interval);
|
||||
WDT_MODE ets_wdt_disable(void);
|
||||
void ets_wdt_restore(WDT_MODE old_mode);
|
||||
/**
|
||||
* @brief Set the real CPU ticks per us to the ets, so that ets_delay_us will be accurate.
|
||||
* Call this function when CPU frequency is changed.
|
||||
*
|
||||
* @param uint32_t ticks_per_us : CPU ticks per us.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void ets_update_cpu_frequency(uint32_t ticks_per_us);
|
||||
|
||||
/* interrupt related */
|
||||
typedef void (* ets_isr_t)(void *);
|
||||
/**
|
||||
* @brief Get the real CPU ticks per us to the ets.
|
||||
* This function do not return real CPU ticks per us, just the record in ets. It can be used to check with the real CPU frequency.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return uint32_t : CPU ticks per us record in ets.
|
||||
*/
|
||||
uint32_t ets_get_cpu_frequency(void);
|
||||
|
||||
#define ETS_WMAC_SOURCE 0
|
||||
#define ETS_SLC_SOURCE 1
|
||||
#define ETS_UART_SOURCE 13
|
||||
#define ETS_UART1_SOURCE 14
|
||||
#define ETS_FRC_TIMER2_SOURCE 43
|
||||
/**
|
||||
* @brief Get xtal_freq/analog_8M*256 value calibrated in rtc module.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return uint32_t : xtal_freq/analog_8M*256.
|
||||
*/
|
||||
uint32_t ets_get_xtal_scale(void);
|
||||
|
||||
#define ETS_WMAC_INUM 0
|
||||
#define ETS_SLC_INUM 1
|
||||
#define ETS_SPI_INUM 2
|
||||
#define ETS_HSIP_INUM 2
|
||||
#define ETS_I2S_INUM 2
|
||||
#define ETS_RTC_INUM 3
|
||||
#define ETS_FRC_TIMER1_INUM 9 /* use edge*/
|
||||
#define ETS_FRC_TIMER2_INUM 10 /* use edge*/
|
||||
#define ETS_WDT_INUM 8 /* use edge*/
|
||||
#define ETS_GPIO_INUM 4
|
||||
#define ETS_UART_INUM 5
|
||||
#define ETS_UART1_INUM 5
|
||||
#define ETS_MAX_INUM 6
|
||||
/**
|
||||
* @brief Get xtal_freq value, If value not stored in RTC_STORE5, than store.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return uint32_t : if rtc store the value (RTC_STORE5 high 16 bits and low 16 bits with same value), read from rtc register.
|
||||
* clock = (REG_READ(RTC_STORE5) & 0xffff) << 12;
|
||||
* else if analog_8M in efuse
|
||||
* clock = ets_get_xtal_scale() * 15625 * ets_efuse_get_8M_clock() / 40;
|
||||
* else clock = 26M.
|
||||
*/
|
||||
uint32_t ets_get_detected_xtal_freq(void);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/** \defgroup ets_intr_apis, ets interrupt configure related apis
|
||||
* @brief ets intr apis
|
||||
*/
|
||||
|
||||
/** @addtogroup ets_intr_apis
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef void (* ets_isr_t)(void *);/**< interrupt handler type*/
|
||||
|
||||
/**
|
||||
* @brief Attach a interrupt handler to a CPU interrupt number.
|
||||
* This function equals to _xtos_set_interrupt_handler_arg(i, func, arg).
|
||||
* In FreeRTOS, please call FreeRTOS apis, never call this api.
|
||||
*
|
||||
* @param int i : CPU interrupt number.
|
||||
*
|
||||
* @param ets_isr_t func : Interrupt handler.
|
||||
*
|
||||
* @param void *arg : argument of the handler.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void ets_isr_attach(int i, ets_isr_t func, void *arg);
|
||||
|
||||
/**
|
||||
* @brief Mask the interrupts which show in mask bits.
|
||||
* This function equals to _xtos_ints_off(mask).
|
||||
* In FreeRTOS, please call FreeRTOS apis, never call this api.
|
||||
*
|
||||
* @param uint32_t mask : BIT(i) means mask CPU interrupt number i.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void ets_isr_mask(uint32_t mask);
|
||||
|
||||
/**
|
||||
* @brief Unmask the interrupts which show in mask bits.
|
||||
* This function equals to _xtos_ints_on(mask).
|
||||
* In FreeRTOS, please call FreeRTOS apis, never call this api.
|
||||
*
|
||||
* @param uint32_t mask : BIT(i) means mask CPU interrupt number i.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void ets_isr_unmask(uint32_t unmask);
|
||||
|
||||
/**
|
||||
* @brief Lock the interrupt to level 2.
|
||||
* This function direct set the CPU registers.
|
||||
* In FreeRTOS, please call FreeRTOS apis, never call this api.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void ets_intr_lock(void);
|
||||
|
||||
/**
|
||||
* @brief Unlock the interrupt to level 0.
|
||||
* This function direct set the CPU registers.
|
||||
* In FreeRTOS, please call FreeRTOS apis, never call this api.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void ets_intr_unlock(void);
|
||||
|
||||
/**
|
||||
* @brief Unlock the interrupt to level 0, and CPU will go into power save mode(wait interrupt).
|
||||
* This function direct set the CPU registers.
|
||||
* In FreeRTOS, please call FreeRTOS apis, never call this api.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void ets_waiti0(void);
|
||||
|
||||
/**
|
||||
* @brief Attach an CPU interrupt to a hardware source.
|
||||
* We have 4 steps to use an interrupt:
|
||||
* 1.Attach hardware interrupt source to CPU. intr_matrix_set(0, ETS_WIFI_MAC_INTR_SOURCE, ETS_WMAC_INUM);
|
||||
* 2.Set interrupt handler. xt_set_interrupt_handler(ETS_WMAC_INUM, func, NULL);
|
||||
* 3.Enable interrupt for CPU. xt_ints_on(1 << ETS_WMAC_INUM);
|
||||
* 4.Enable interrupt in the module.
|
||||
*
|
||||
* @param int cpu_no : The CPU which the interrupt number belongs.
|
||||
*
|
||||
* @param uint32_t model_num : The interrupt hardware source number, please see the interrupt hardware source table.
|
||||
*
|
||||
* @param uint32_t intr_num : The interrupt number CPU, please see the interrupt cpu using table.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void intr_matrix_set(int cpu_no, uint32_t model_num, uint32_t intr_num);
|
||||
|
||||
#define _ETSTR(v) # v
|
||||
@ -194,126 +523,80 @@ void intr_matrix_set(int cpu_no, uint32_t model_num, uint32_t intr_num);
|
||||
: "=a" (__tmp) : : "memory" ); \
|
||||
})
|
||||
|
||||
#ifdef CONFIG_NONE_OS
|
||||
#define ETS_INTR_LOCK() \
|
||||
ets_intr_lock()
|
||||
ets_intr_lock()
|
||||
|
||||
#define ETS_INTR_UNLOCK() \
|
||||
ets_intr_unlock()
|
||||
|
||||
#define ETS_CCOMPARE_INTR_ATTACH(func, arg) \
|
||||
ets_isr_attach(ETS_CCOMPARE_INUM, (func), (void *)(arg))
|
||||
|
||||
#define ETS_PWM_INTR_ATTACH(func, arg) \
|
||||
ets_isr_attach(ETS_PWM_INUM, (func), (void *)(arg))
|
||||
|
||||
#define ETS_WMAC_INTR_ATTACH(func, arg) \
|
||||
ets_isr_attach(ETS_WMAC_INUM, (func), (void *)(arg))
|
||||
|
||||
#define ETS_FRC_TIMER1_INTR_ATTACH(func, arg) \
|
||||
ets_isr_attach(ETS_FRC_TIMER1_INUM, (func), (void *)(arg))
|
||||
|
||||
#define ETS_FRC_TIMER2_INTR_ATTACH(func, arg) \
|
||||
ets_isr_attach(ETS_FRC_TIMER2_INUM, (func), (void *)(arg))
|
||||
|
||||
#define ETS_GPIO_INTR_ATTACH(func, arg) \
|
||||
ets_isr_attach(ETS_GPIO_INUM, (func), (void *)(arg))
|
||||
|
||||
#define ETS_UART_INTR_ATTACH(func, arg) \
|
||||
ets_isr_attach(ETS_UART_INUM, (func), (void *)(arg))
|
||||
|
||||
#define ETS_WDT_INTR_ATTACH(func, arg) \
|
||||
ets_isr_attach(ETS_WDT_INUM, (func), (void *)(arg))
|
||||
|
||||
#define ETS_RTC_INTR_ATTACH(func, arg) \
|
||||
ets_isr_attach(ETS_RTC_INUM, (func), (void *)(arg))
|
||||
|
||||
#define ETS_SLC_INTR_ATTACH(func, arg) \
|
||||
ets_isr_attach(ETS_SLC_INUM, (func), (void *)(arg))
|
||||
ets_intr_unlock()
|
||||
|
||||
#define ETS_ISR_ATTACH \
|
||||
ets_isr_attach
|
||||
|
||||
#define ETS_INTR_ENABLE(inum) \
|
||||
xt_ints_on((1<<inum))
|
||||
ets_isr_unmask((1<<inum))
|
||||
|
||||
#define ETS_INTR_DISABLE(inum) \
|
||||
xt_ints_off((1<<inum))
|
||||
ets_isr_mask((1<<inum))
|
||||
|
||||
#define ETS_CCOMPARE_INTR_ENBALE() \
|
||||
ETS_INTR_ENABLE(ETS_CCOMPARE_INUM)
|
||||
#define ETS_WMAC_INTR_ATTACH(func, arg) \
|
||||
ETS_ISR_ATTACH(ETS_WMAC_INUM, (func), (void *)(arg))
|
||||
|
||||
#define ETS_CCOMPARE_INTR_DISBALE() \
|
||||
ETS_INTR_DISABLE(ETS_CCOMPARE_INUM)
|
||||
#define ETS_TG0_T0_INTR_ATTACH(func, arg) \
|
||||
ETS_ISR_ATTACH(ETS_TG0_T0_INUM, (func), (void *)(arg))
|
||||
|
||||
#define ETS_PWM_INTR_ENABLE() \
|
||||
ETS_INTR_ENABLE(ETS_PWM_INUM)
|
||||
#define ETS_GPIO_INTR_ATTACH(func, arg) \
|
||||
ETS_ISR_ATTACH(ETS_GPIO_INUM, (func), (void *)(arg))
|
||||
|
||||
#define ETS_PWM_INTR_DISABLE() \
|
||||
ETS_INTR_DISABLE(ETS_PWM_INUM)
|
||||
#define ETS_UART0_INTR_ATTACH(func, arg) \
|
||||
ETS_ISR_ATTACH(ETS_UART0_INUM, (func), (void *)(arg))
|
||||
|
||||
#define ETS_WDT_INTR_ATTACH(func, arg) \
|
||||
ETS_ISR_ATTACH(ETS_WDT_INUM, (func), (void *)(arg))
|
||||
|
||||
#define ETS_SLC_INTR_ATTACH(func, arg) \
|
||||
ETS_ISR_ATTACH(ETS_SLC_INUM, (func), (void *)(arg))
|
||||
|
||||
#define ETS_BB_INTR_ENABLE() \
|
||||
ETS_INTR_ENABLE(ETS_BB_INUM)
|
||||
ETS_INTR_ENABLE(ETS_BB_INUM)
|
||||
|
||||
#define ETS_BB_INTR_DISABLE() \
|
||||
ETS_INTR_DISABLE(ETS_BB_INUM)
|
||||
ETS_INTR_DISABLE(ETS_BB_INUM)
|
||||
|
||||
#define ETS_UART_INTR_ENABLE() \
|
||||
ETS_INTR_ENABLE(ETS_UART_INUM)
|
||||
#define ETS_UART0_INTR_ENABLE() \
|
||||
ETS_INTR_ENABLE(ETS_UART0_INUM)
|
||||
|
||||
#define ETS_UART_INTR_DISABLE() \
|
||||
ETS_INTR_DISABLE(ETS_UART_INUM)
|
||||
#define ETS_UART0_INTR_DISABLE() \
|
||||
ETS_INTR_DISABLE(ETS_UART0_INUM)
|
||||
|
||||
#define ETS_GPIO_INTR_ENABLE() \
|
||||
ETS_INTR_ENABLE(ETS_GPIO_INUM)
|
||||
ETS_INTR_ENABLE(ETS_GPIO_INUM)
|
||||
|
||||
#define ETS_GPIO_INTR_DISABLE() \
|
||||
ETS_INTR_DISABLE(ETS_GPIO_INUM)
|
||||
|
||||
ETS_INTR_DISABLE(ETS_GPIO_INUM)
|
||||
|
||||
#define ETS_WDT_INTR_ENABLE() \
|
||||
ETS_INTR_ENABLE(ETS_WDT_INUM)
|
||||
ETS_INTR_ENABLE(ETS_WDT_INUM)
|
||||
|
||||
#define ETS_WDT_INTR_DISABLE() \
|
||||
ETS_INTR_DISABLE(ETS_WDT_INUM)
|
||||
ETS_INTR_DISABLE(ETS_WDT_INUM)
|
||||
|
||||
#define ETS_FRC1_INTR_ENABLE() \
|
||||
ETS_INTR_ENABLE(ETS_FRC_TIMER1_INUM)
|
||||
#define ETS_TG0_T0_INTR_ENABLE() \
|
||||
ETS_INTR_ENABLE(ETS_TG0_T0_INUM)
|
||||
|
||||
#define ETS_FRC1_INTR_DISABLE() \
|
||||
ETS_INTR_DISABLE(ETS_FRC_TIMER1_INUM)
|
||||
|
||||
#define ETS_FRC2_INTR_ENABLE() \
|
||||
ETS_INTR_ENABLE(ETS_FRC_TIMER2_INUM)
|
||||
|
||||
#define ETS_FRC2_INTR_DISABLE() \
|
||||
ETS_INTR_DISABLE(ETS_FRC_TIMER2_INUM)
|
||||
|
||||
#define ETS_RTC_INTR_ENABLE() \
|
||||
ETS_INTR_ENABLE(ETS_RTC_INUM)
|
||||
|
||||
#define ETS_RTC_INTR_DISABLE() \
|
||||
ETS_INTR_DISABLE(ETS_RTC_INUM)
|
||||
#define ETS_TG0_T0_INTR_DISABLE() \
|
||||
ETS_INTR_DISABLE(ETS_TG0_T0_INUM)
|
||||
|
||||
#define ETS_SLC_INTR_ENABLE() \
|
||||
ETS_INTR_ENABLE(ETS_SLC_INUM)
|
||||
ETS_INTR_ENABLE(ETS_SLC_INUM)
|
||||
|
||||
#define ETS_SLC_INTR_DISABLE() \
|
||||
ETS_INTR_DISABLE(ETS_SLC_INUM)
|
||||
|
||||
void ets_delay_us(uint32_t us);
|
||||
void ets_update_cpu_frequency(uint32_t ticks_per_us);
|
||||
uint32_t ets_get_xtal_scale();
|
||||
uint32_t ets_get_detected_xtal_freq();
|
||||
|
||||
#if 0
|
||||
#define isdigit(c) ((c >= '0') && (c <= '9'))
|
||||
|
||||
#define isxdigit(c) (((c >= '0') && (c <= '9')) || \
|
||||
((c >= 'a') && (c <= 'f')) || \
|
||||
((c >= 'A') && (c <= 'F')) )
|
||||
|
||||
#define isblank(c) ((c == ' ') || (c == '\t'))
|
||||
|
||||
#define isupper(c) ((c >= 'A') && (c <= 'Z'))
|
||||
ETS_INTR_DISABLE(ETS_SLC_INUM)
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifndef MAC2STR
|
||||
#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
|
||||
@ -322,6 +605,10 @@ uint32_t ets_get_detected_xtal_freq();
|
||||
|
||||
#define ETS_MEM_BAR() asm volatile ( "" : : : "memory" )
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -25,6 +25,14 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup gpio_apis, uart configuration and communication related apis
|
||||
* @brief gpio apis
|
||||
*/
|
||||
|
||||
/** @addtogroup gpio_apis
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define GPIO_REG_READ(reg) READ_PERI_REG(reg)
|
||||
#define GPIO_REG_WRITE(reg, val) WRITE_PERI_REG(reg, val)
|
||||
#define GPIO_PIN_COUNT 40
|
||||
@ -37,17 +45,14 @@ extern "C" {
|
||||
|
||||
#define GPIO_REGID_TO_PINIDX(reg_id) ((reg_id) - GPIO_ID_PIN0)
|
||||
|
||||
typedef enum{
|
||||
GPIO_PIN_INTR_DISABLE = 0,
|
||||
GPIO_PIN_INTR_POSEDGE = 1,
|
||||
GPIO_PIN_INTR_NEGEDGE = 2,
|
||||
GPIO_PIN_INTR_ANYEGDE = 3,
|
||||
GPIO_PIN_INTR_LOLEVEL = 4,
|
||||
GPIO_PIN_INTR_HILEVEL = 5
|
||||
}GPIO_INT_TYPE;
|
||||
|
||||
#define GREEN_LED_ON() GPIO_OUTPUT_SET(GPIO_ID_PIN(1) , 0)
|
||||
#define GREEN_LED_OFF() GPIO_OUTPUT_SET(GPIO_ID_PIN(1) , 1)
|
||||
typedef enum {
|
||||
GPIO_PIN_INTR_DISABLE = 0,
|
||||
GPIO_PIN_INTR_POSEDGE = 1,
|
||||
GPIO_PIN_INTR_NEGEDGE = 2,
|
||||
GPIO_PIN_INTR_ANYEGDE = 3,
|
||||
GPIO_PIN_INTR_LOLEVEL = 4,
|
||||
GPIO_PIN_INTR_HILEVEL = 5
|
||||
} GPIO_INT_TYPE;
|
||||
|
||||
#define GPIO_OUTPUT_SET(gpio_no, bit_value) \
|
||||
((gpio_no < 32) ? gpio_output_set(bit_value<<gpio_no, (bit_value ? 0 : 1)<<gpio_no, 1<<gpio_no,0) : \
|
||||
@ -58,82 +63,235 @@ typedef enum{
|
||||
/* GPIO interrupt handler, registered through gpio_intr_handler_register */
|
||||
typedef void (* gpio_intr_handler_fn_t)(uint32_t intr_mask, bool high, void *arg);
|
||||
|
||||
/**
|
||||
* @brief Initialize GPIO. This includes reading the GPIO Configuration DataSet
|
||||
* to initialize "output enables" and pin configurations for each gpio pin.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void gpio_init(void);
|
||||
|
||||
/*
|
||||
* Initialize GPIO. This includes reading the GPIO Configuration DataSet
|
||||
* to initialize "output enables" and pin configurations for each gpio pin.
|
||||
* Must be called once during startup.
|
||||
*/
|
||||
void gpio_init(void) ROMFN_ATTR;
|
||||
/**
|
||||
* @brief Change GPIO(0-31) pin output by setting, clearing, or disabling pins, GPIO0<->BIT(0).
|
||||
* There is no particular ordering guaranteed; so if the order of writes is significant,
|
||||
* calling code should divide a single call into multiple calls.
|
||||
*
|
||||
* @param uint32_t set_mask : the gpios that need high level.
|
||||
*
|
||||
* @param uint32_t clear_mask : the gpios that need low level.
|
||||
*
|
||||
* @param uint32_t enable_mask : the gpios that need be changed.
|
||||
*
|
||||
* @param uint32_t disable_mask : the gpios that need diable output.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void gpio_output_set(uint32_t set_mask, uint32_t clear_mask, uint32_t enable_mask, uint32_t disable_mask);
|
||||
|
||||
/*
|
||||
* Change GPIO pin output by setting, clearing, or disabling pins.
|
||||
* In general, it is expected that a bit will be set in at most one
|
||||
* of these masks. If a bit is clear in all masks, the output state
|
||||
* remains unchanged.
|
||||
*
|
||||
* There is no particular ordering guaranteed; so if the order of
|
||||
* writes is significant, calling code should divide a single call
|
||||
* into multiple calls.
|
||||
*/
|
||||
void gpio_output_set(uint32_t set_mask,
|
||||
uint32_t clear_mask,
|
||||
uint32_t enable_mask,
|
||||
uint32_t disable_mask) ROMFN_ATTR;
|
||||
void gpio_output_set_high(uint32_t set_mask,
|
||||
uint32_t clear_mask,
|
||||
uint32_t enable_mask,
|
||||
uint32_t disable_mask) ROMFN_ATTR;
|
||||
/*
|
||||
* Sample the value of GPIO input pins and returns a bitmask.
|
||||
*/
|
||||
uint32_t gpio_input_get(void) ROMFN_ATTR;
|
||||
uint32_t gpio_input_get_high(void) ROMFN_ATTR;
|
||||
/**
|
||||
* @brief Change GPIO(32-39) pin output by setting, clearing, or disabling pins, GPIO32<->BIT(0).
|
||||
* There is no particular ordering guaranteed; so if the order of writes is significant,
|
||||
* calling code should divide a single call into multiple calls.
|
||||
*
|
||||
* @param uint32_t set_mask : the gpios that need high level.
|
||||
*
|
||||
* @param uint32_t clear_mask : the gpios that need low level.
|
||||
*
|
||||
* @param uint32_t enable_mask : the gpios that need be changed.
|
||||
*
|
||||
* @param uint32_t disable_mask : the gpios that need diable output.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void gpio_output_set_high(uint32_t set_mask, uint32_t clear_mask, uint32_t enable_mask, uint32_t disable_mask);
|
||||
|
||||
/*
|
||||
* Set the specified GPIO register to the specified value.
|
||||
* This is a very general and powerful interface that is not
|
||||
* expected to be used during normal operation. It is intended
|
||||
* mainly for debug, or for unusual requirements.
|
||||
*/
|
||||
void gpio_register_set(uint32_t reg_id, uint32_t value) ROMFN_ATTR;
|
||||
/**
|
||||
* @brief Sample the value of GPIO input pins(0-31) and returns a bitmask.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return uint32_t : bitmask for GPIO input pins, BIT(0) for GPIO0.
|
||||
*/
|
||||
uint32_t gpio_input_get(void);
|
||||
|
||||
/* Get the current value of the specified GPIO register. */
|
||||
uint32_t gpio_register_get(uint32_t reg_id) ROMFN_ATTR;
|
||||
/**
|
||||
* @brief Sample the value of GPIO input pins(32-39) and returns a bitmask.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return uint32_t : bitmask for GPIO input pins, BIT(0) for GPIO32.
|
||||
*/
|
||||
uint32_t gpio_input_get_high(void);
|
||||
|
||||
/*
|
||||
* Register an application-specific interrupt handler for GPIO pin
|
||||
* interrupts. Once the interrupt handler is called, it will not
|
||||
* be called again until after a call to gpio_intr_ack. Any GPIO
|
||||
* interrupts that occur during the interim are masked.
|
||||
*
|
||||
* The application-specific handler is called with a mask of
|
||||
* pending GPIO interrupts. After processing pin interrupts, the
|
||||
* application-specific handler may wish to use gpio_intr_pending
|
||||
* to check for any additional pending interrupts before it returns.
|
||||
*/
|
||||
void gpio_intr_handler_register(gpio_intr_handler_fn_t fn, void *arg) ROMFN_ATTR;
|
||||
/**
|
||||
* @brief Register an application-specific interrupt handler for GPIO pin interrupts.
|
||||
* Once the interrupt handler is called, it will not be called again until after a call to gpio_intr_ack.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param gpio_intr_handler_fn_t fn : gpio application-specific interrupt handler
|
||||
*
|
||||
* @param void *arg : gpio application-specific interrupt handler argument.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void gpio_intr_handler_register(gpio_intr_handler_fn_t fn, void *arg);
|
||||
|
||||
/* Determine which GPIO interrupts are pending. */
|
||||
uint32_t gpio_intr_pending(void) ROMFN_ATTR;
|
||||
uint32_t gpio_intr_pending_high(void) ROMFN_ATTR;
|
||||
/**
|
||||
* @brief Get gpio interrupts which happens but not processed.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return uint32_t : bitmask for GPIO pending interrupts, BIT(0) for GPIO0.
|
||||
*/
|
||||
uint32_t gpio_intr_pending(void);
|
||||
|
||||
/*
|
||||
* Acknowledge GPIO interrupts.
|
||||
* Intended to be called from the gpio_intr_handler_fn.
|
||||
*/
|
||||
void gpio_intr_ack(uint32_t ack_mask) ROMFN_ATTR;
|
||||
void gpio_intr_ack_high(uint32_t ack_mask) ROMFN_ATTR;
|
||||
/**
|
||||
* @brief Get gpio interrupts which happens but not processed.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return uint32_t : bitmask for GPIO pending interrupts, BIT(0) for GPIO32.
|
||||
*/
|
||||
uint32_t gpio_intr_pending_high(void);
|
||||
|
||||
void gpio_pin_wakeup_enable(uint32_t i, GPIO_INT_TYPE intr_state) ROMFN_ATTR;
|
||||
/**
|
||||
* @brief Ack gpio interrupts to process pending interrupts.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param uint32_t ack_mask: bitmask for GPIO ack interrupts, BIT(0) for GPIO0.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void gpio_intr_ack(uint32_t ack_mask);
|
||||
|
||||
void gpio_pin_wakeup_disable() ROMFN_ATTR;
|
||||
/**
|
||||
* @brief Ack gpio interrupts to process pending interrupts.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param uint32_t ack_mask: bitmask for GPIO ack interrupts, BIT(0) for GPIO32.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void gpio_intr_ack_high(uint32_t ack_mask);
|
||||
|
||||
//extern void gpio_module_install(struct gpio_api *api);
|
||||
/**
|
||||
* @brief Set GPIO to wakeup the ESP32.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param uint32_t i: gpio number.
|
||||
*
|
||||
* @param GPIO_INT_TYPE intr_state : only GPIO_PIN_INTR_LOLEVEL\GPIO_PIN_INTR_HILEVEL can be used
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void gpio_pin_wakeup_enable(uint32_t i, GPIO_INT_TYPE intr_state);
|
||||
|
||||
void gpio_matrix_in(uint32_t gpio, uint32_t signal_idx, bool inv) ROMFN_ATTR;
|
||||
/**
|
||||
* @brief disable GPIOs to wakeup the ESP32.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void gpio_pin_wakeup_disable(void);
|
||||
|
||||
void gpio_matrix_out(uint32_t gpio, uint32_t signal_idx, bool out_inv, bool oen_inv) ROMFN_ATTR;
|
||||
/**
|
||||
* @brief set gpio input to a signal, one gpio can input to several signals.
|
||||
*
|
||||
* @param uint32_t gpio : gpio number, 0~0x27
|
||||
* gpio == 0x30, input 0 to signal
|
||||
* gpio == 0x34, ???
|
||||
* gpio == 0x38, input 1 to signal
|
||||
*
|
||||
* @param uint32_t signal_idx : signal index.
|
||||
*
|
||||
* @param bool inv : the signal is inv or not
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void gpio_matrix_in(uint32_t gpio, uint32_t signal_idx, bool inv);
|
||||
|
||||
/**
|
||||
* @brief set signal output to gpio, one signal can output to several gpios.
|
||||
*
|
||||
* @param uint32_t gpio : gpio number, 0~0x27
|
||||
*
|
||||
* @param uint32_t signal_idx : signal index.
|
||||
* signal_idx == 0x100, cancel output put to the gpio
|
||||
*
|
||||
* @param bool out_inv : the signal output is inv or not
|
||||
*
|
||||
* @param bool oen_inv : the signal output enable is inv or not
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void gpio_matrix_out(uint32_t gpio, uint32_t signal_idx, bool out_inv, bool oen_inv);
|
||||
|
||||
/**
|
||||
* @brief Select pad as a gpio function from IOMUX.
|
||||
*
|
||||
* @param uint32_t gpio_num : gpio number, 0~0x27
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void gpio_pad_select_gpio(uint8_t gpio_num);
|
||||
|
||||
/**
|
||||
* @brief Set pad driver capability.
|
||||
*
|
||||
* @param uint32_t gpio_num : gpio number, 0~0x27
|
||||
*
|
||||
* @param uint8_t drv : 0-3
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void gpio_pad_set_drv(uint8_t gpio_num, uint8_t drv);
|
||||
|
||||
/**
|
||||
* @brief Pull up the pad from gpio number.
|
||||
*
|
||||
* @param uint32_t gpio_num : gpio number, 0~0x27
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void gpio_pad_pullup(uint8_t gpio_num);
|
||||
|
||||
/**
|
||||
* @brief Pull down the pad from gpio number.
|
||||
*
|
||||
* @param uint32_t gpio_num : gpio number, 0~0x27
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void gpio_pad_pulldown(uint8_t gpio_num);
|
||||
|
||||
/**
|
||||
* @brief Unhold the pad from gpio number.
|
||||
*
|
||||
* @param uint32_t gpio_num : gpio number, 0~0x27
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void gpio_pad_unhold(uint8_t gpio_num);
|
||||
|
||||
/**
|
||||
* @brief Hold the pad from gpio number.
|
||||
*
|
||||
* @param uint32_t gpio_num : gpio number, 0~0x27
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void gpio_pad_hold(uint8_t gpio_num);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -26,30 +26,68 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup rtc_apis, rtc registers and memory related apis
|
||||
* @brief rtc apis
|
||||
*/
|
||||
|
||||
/** @addtogroup rtc_apis
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**************************************************************************************
|
||||
* Note: *
|
||||
* Some Rtc memory and registers are used, in ROM or in internal library. *
|
||||
* Please do not use reserved or used rtc memory or registers. *
|
||||
* *
|
||||
*************************************************************************************
|
||||
* RTC Memory & Store Register usage
|
||||
*************************************************************************************
|
||||
* rtc memory addr type size usage
|
||||
* 0x3ff61000(0x50000000) Slow SIZE_CP Co-Processor code/Reset Entry
|
||||
* 0x3ff61000+SIZE_CP Slow 6144-SIZE_CP
|
||||
* 0x3ff62800 Slow 2048 Reserved
|
||||
*
|
||||
* 0x3ff80000(0x400c0000) Fast 8192 deep sleep entry code
|
||||
*
|
||||
*************************************************************************************
|
||||
* Rtc store registers usage
|
||||
* RTC_STORE0
|
||||
* RTC_STORE1
|
||||
* RTC_STORE2
|
||||
* RTC_STORE3
|
||||
* RTC_STORE4 Reserved
|
||||
* RTC_STORE5 External Xtal Frequency
|
||||
* RTC_STORE6 FAST_RTC_MEMORY_ENTRY
|
||||
* RTC_STORE7 FAST_RTC_MEMORY_CRC
|
||||
*************************************************************************************
|
||||
*/
|
||||
#define RTC_ENTRY_ADDR RTC_STORE6
|
||||
#define RTC_MEMORY_CRC RTC_STORE7
|
||||
|
||||
|
||||
typedef enum {
|
||||
AWAKE = 0, //CPU ON
|
||||
AWAKE = 0, //<CPU ON
|
||||
LIGHT_SLEEP = BIT0, //CPU waiti, PLL ON. We don't need explicitly set this mode.
|
||||
DEEP_SLEEP = BIT1 //CPU OFF, PLL OFF, only specific timer could wake up
|
||||
} SLEEP_MODE;
|
||||
|
||||
typedef enum {
|
||||
NO_MEAN = 0,
|
||||
POWERON_RESET = 1, //1 Vbat power on reset, RTC reset
|
||||
// EXT_SYS_RESET = 2, //4 External System reset, RTC reset
|
||||
SW_RESET = 3, //6 Software warm reset
|
||||
OWDT_RESET = 4, //5 Watch dog reset
|
||||
DEEPSLEEP_RESET = 5, //2 Deep sleep timer reach reset.
|
||||
SDIO_RESET = 6, //3 Deep sleep Pbint power on reset [boot]
|
||||
TG0WDT_SYS_RESET = 7,
|
||||
TG1WDT_SYS_RESET = 8,
|
||||
RTCWDT_SYS_RESET = 9,
|
||||
INTRUSION_RESET = 10,
|
||||
TGWDT_CPU_RESET = 11,
|
||||
SW_CPU_RESET = 12,
|
||||
RTCWDT_CPU_RESET = 13,
|
||||
EXT_CPU_RESET = 14,
|
||||
RTCWDT_BROWN_OUT_RESET = 15,
|
||||
RTCWDT_RTC_RESET = 16
|
||||
POWERON_RESET = 1, /**<1, Vbat power on reset*/
|
||||
SW_RESET = 3, /**<3, Software reset digital core*/
|
||||
OWDT_RESET = 4, /**<4, Legacy watch dog reset digital core*/
|
||||
DEEPSLEEP_RESET = 5, /**<3, Deep Sleep reset digital core*/
|
||||
SDIO_RESET = 6, /**<6, Reset by SLC module, reset digital core*/
|
||||
TG0WDT_SYS_RESET = 7, /**<7, Timer Group0 Watch dog reset digital core*/
|
||||
TG1WDT_SYS_RESET = 8, /**<8, Timer Group1 Watch dog reset digital core*/
|
||||
RTCWDT_SYS_RESET = 9, /**<9, RTC Watch dog Reset digital core*/
|
||||
INTRUSION_RESET = 10, /**<10, Instrusion tested to reset CPU*/
|
||||
TGWDT_CPU_RESET = 11, /**<11, Time Group reset CPU*/
|
||||
SW_CPU_RESET = 12, /**<12, Software reset CPU*/
|
||||
RTCWDT_CPU_RESET = 13, /**<13, RTC Watch dog Reset CPU*/
|
||||
EXT_CPU_RESET = 14, /**<14, for APP CPU, reseted by PRO CPU*/
|
||||
RTCWDT_BROWN_OUT_RESET = 15, /**<15, Reset when the vdd voltage is not stable*/
|
||||
RTCWDT_RTC_RESET = 16 /**<16, RTC Watch dog reset digital core and rtc module*/
|
||||
} RESET_REASON;
|
||||
|
||||
typedef enum {
|
||||
@ -98,67 +136,67 @@ typedef enum {
|
||||
SDIO_IDLE_INT_EN = SDIO_IDLE_INT,
|
||||
RTC_WDT_INT_EN = RTC_WDT_INT,
|
||||
RTC_TIME_VALID_INT_EN = RTC_TIME_VALID_INT
|
||||
}RTC_INT_EN;
|
||||
|
||||
|
||||
|
||||
// Alive memory is a special memory block which could restore data during system
|
||||
// deep sleep. power management and wlan profile data may need put into this
|
||||
// memory area.
|
||||
// Should create a dram segment in link script.
|
||||
#define ALIVE_MEMORY_ADDR
|
||||
#define ALIVE_MEMORY_SIZE (1024 * 2)
|
||||
|
||||
void rtc_hw_init(void);
|
||||
} RTC_INT_EN;
|
||||
|
||||
/**
|
||||
* @brief Get the reset reason for CPU.
|
||||
*
|
||||
* @param int cpu_no : CPU no.
|
||||
*
|
||||
* @return RESET_REASON
|
||||
*/
|
||||
RESET_REASON rtc_get_reset_reason(int cpu_no);
|
||||
|
||||
/**
|
||||
* @brief Get the wakeup cause for CPU.
|
||||
*
|
||||
* @param int cpu_no : CPU no.
|
||||
*
|
||||
* @return WAKEUP_REASON
|
||||
*/
|
||||
WAKEUP_REASON rtc_get_wakeup_cause(void);
|
||||
|
||||
/**
|
||||
* @brief Get CRC for Fast RTC Memory.
|
||||
*
|
||||
* @param uint32_t start_addr : 0 - 0x7ff for Fast RTC Memory.
|
||||
*
|
||||
* @param uint32_t crc_len : 0 - 0x7ff, 0 for 1 byte, 0x7ff for 0x800 byte.
|
||||
*
|
||||
* @return uint32_t : CRC32 result
|
||||
*/
|
||||
uint32_t calc_rtc_memory_crc(uint32_t start_addr, uint32_t crc_len);
|
||||
|
||||
/**
|
||||
* @brief Set CRC of Fast RTC memory 0-0x7ff into RTC STORE7.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void set_rtc_memory_crc(void);
|
||||
|
||||
/**
|
||||
* @brief Software Reset digital core.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void software_reset(void);
|
||||
|
||||
/**
|
||||
* @brief Software Reset digital core.
|
||||
*
|
||||
* @param int cpu_no : The CPU to reset, 0 for PRO CPU, 1 for APP CPU.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void software_reset_cpu(int cpu_no);
|
||||
void rtc_select_apb_bridge(bool sel);
|
||||
void rtc_set_sleep_mode(SLEEP_MODE mode, uint32_t sleep_sec, uint32_t wakeup_mode);
|
||||
|
||||
uint8_t ets_rtc_recovery(void);
|
||||
|
||||
#define MAX_DEEPSLEEP_DURATION (0xffffffff / RTC_CLK_FREQ)
|
||||
#define SECOND_TO_RTC_TICK(second) ((second)*RTC_CLK_FREQ) //32KHz
|
||||
#define CALIB_VALUE_TO_RTC_TICK(microsecond, clk_mkz, n_rtc,nclk) ((microsecond)*(clk_mkz)*(n_rtc)/(nclk)) //32KHz
|
||||
#define RTC_TICK_TO_SECOND(tick) ((tick)/RTC_CLK_FREQ )
|
||||
#define GET_CURRENT_TICK() (READ_PERI_REG(RTC_TIME))
|
||||
#define SET_WAKEUP_TICK(tick) (WRITE_PERI_REG(RTC_TIMER0, tick))
|
||||
|
||||
//#define GET_WAKEUP_CAUSE() GET_PERI_REG_BITS2(RTC_STATE1, RTC_CNTL_WAKEUP_CAUSE, RTC_CNTL_WAKEUP_CAUSE_S)
|
||||
#define DISABLE_RTC_INT(int_type) CLEAR_PERI_REG_MASK(RTC_INT_ENA, int_type)
|
||||
#define ENABLE_RTC_INT(int_type) SET_PERI_REG_MASK(RTC_INT_ENA, int_type)
|
||||
#define CLR_RTC_INT(int_type) SET_PERI_REG_MASK(RTC_INT_CLR, int_type)
|
||||
#define GET_RTC_INT_CAUSE() GET_PERI_REG_BITS(RTC_INT_RAW, RTC_INT_RAW_MSB,RTC_INT_RAW_LSB)
|
||||
|
||||
void rtc_register_deepsleep_timer(ETSTimer *timer, uint32_t tmout);
|
||||
void rtc_disable_deepsleep_timer(void);
|
||||
|
||||
void rtc_enter_sleep(void);
|
||||
void ets_rtc_int_register(void);
|
||||
void dtm_set_intr_mask(uint32_t mask);
|
||||
uint32_t dtm_get_intr_mask(void);
|
||||
void dtm_set_params(uint32_t sleep_mode, uint32_t sleep_tm_ms, uint32_t wakeup_tm_ms, uint32_t sleep_times, uint32_t rxbcn_len);
|
||||
void save_rxbcn_mactime(uint32_t rxbcn_mactime);
|
||||
void save_tsf_us(uint32_t tsf_us);
|
||||
|
||||
typedef void (* ets_idle_cb_t)(void *arg);
|
||||
|
||||
typedef uint32_t (* ETS_GET_MACTIME)(void);
|
||||
typedef void (* ETS_WAKEUP_INIT)(void);
|
||||
|
||||
void dtm_params_init(ETS_GET_MACTIME get_mactime, ETS_WAKEUP_INIT wakeup_init);
|
||||
|
||||
void ets_set_idle_cb(ets_idle_cb_t func, void *arg);
|
||||
|
||||
void ets_enter_sleep(void);
|
||||
|
||||
void rtc_intr_handler(void *);
|
||||
|
||||
#define ETS_SLEEP_START(pfunc, parg) ets_set_idle_cb((pfunc), (parg));
|
||||
|
||||
#define ETS_SLEEP_END() ets_set_idle_cb(NULL, NULL);
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _ROM_SECURE_BOOT_H_
|
||||
#define _ROM_SECURE_BOOT_H_
|
||||
|
||||
@ -34,6 +35,10 @@ void ets_secure_boot_rd_iv(uint32_t *buf);
|
||||
|
||||
void ets_secure_boot_rd_abstract(uint32_t *buf);
|
||||
|
||||
bool ets_secure_boot_check_start(uint8_t abs_index, uint32_t iv_addr);
|
||||
|
||||
int ets_secure_boot_check_finish(uint32_t *abstract);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -11,6 +11,7 @@
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _ROM_SPI_FLASH_H_
|
||||
#define _ROM_SPI_FLASH_H_
|
||||
|
||||
@ -25,6 +26,45 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup spi_flash_apis, spi flash operation related apis
|
||||
* @brief spi_flash apis
|
||||
*/
|
||||
|
||||
/** @addtogroup spi_flash_apis
|
||||
* @{
|
||||
*/
|
||||
|
||||
/*************************************************************
|
||||
* Note
|
||||
*************************************************************
|
||||
* 1. ESP32 chip have 4 SPI slave/master, however, SPI0 is
|
||||
* used as an SPI master to access Flash and ext-SRAM by
|
||||
* Cache module. It will support Decryto read for Flash,
|
||||
* read/write for ext-SRAM. And SPI1 is also used as an
|
||||
* SPI master for Flash read/write and ext-SRAM read/write.
|
||||
* It will support Encrypto write for Flash.
|
||||
* 2. As an SPI master, SPI support Highest clock to 80M,
|
||||
* however, Flash with 80M Clock should be configured
|
||||
* for different Flash chips. If you want to use 80M
|
||||
* clock We should use the SPI that is certified by
|
||||
* Espressif. However, the certification is not started
|
||||
* at the time, so please use 40M clock at the moment.
|
||||
* 3. SPI Flash can use 2 lines or 4 lines mode. If you
|
||||
* use 2 lines mode, you can save two pad SPIHD and
|
||||
* SPIWP for gpio. ESP32 support configured SPI pad for
|
||||
* Flash, the configuration is stored in efuse and flash.
|
||||
* However, the configurations of pads should be certified
|
||||
* by Espressif. If you use this function, please use 40M
|
||||
* clock at the moment.
|
||||
* 4. ESP32 support to use Common SPI command to configure
|
||||
* Flash to QIO mode, if you failed to configure with fix
|
||||
* command. With Common SPI Command, ESP32 can also provide
|
||||
* a way to use same Common SPI command groups on different
|
||||
* Flash chips.
|
||||
* 5. This functions are not protected by packeting, Please use the
|
||||
*************************************************************
|
||||
*/
|
||||
|
||||
#define PERIPHS_SPI_FLASH_CMD SPI_CMD(1)
|
||||
#define PERIPHS_SPI_FLASH_ADDR SPI_ADDR(1)
|
||||
#define PERIPHS_SPI_FLASH_CTRL SPI_CTRL(1)
|
||||
@ -92,7 +132,7 @@ typedef enum {
|
||||
SPI_FLASH_RESULT_TIMEOUT
|
||||
} SpiFlashOpResult;
|
||||
|
||||
typedef struct{
|
||||
typedef struct {
|
||||
uint32_t deviceId;
|
||||
uint32_t chip_size; // chip size in bytes
|
||||
uint32_t block_size;
|
||||
@ -110,33 +150,362 @@ typedef struct {
|
||||
uint16_t data;
|
||||
} SpiCommonCmd;
|
||||
|
||||
void SelectSpiQIO(uint8_t wp_gpio_num, uint32_t ishspi) ROMFN_ATTR;
|
||||
void SetSpiDrvs(uint8_t wp_gpio_num, uint32_t ishspi, uint8_t* drvs) ROMFN_ATTR;
|
||||
void SelectSpiFunction(uint32_t ishspi) ROMFN_ATTR;
|
||||
SpiFlashOpResult SPIEraseChip(void) ROMFN_ATTR;
|
||||
SpiFlashOpResult SPIEraseBlock(uint32_t block_num) ROMFN_ATTR;
|
||||
SpiFlashOpResult SPIEraseSector(uint32_t sector_num) ROMFN_ATTR;
|
||||
SpiFlashOpResult SPIWrite(uint32_t dest_addr, const uint32_t* src, int32_t len) ROMFN_ATTR;
|
||||
void SPI_Write_Encrypt_Enable() ROMFN_ATTR;
|
||||
SpiFlashOpResult SPI_Prepare_Encrypt_Data(uint32_t flash_addr, uint32_t* data) ROMFN_ATTR;
|
||||
void SPI_Write_Encrypt_Disable() ROMFN_ATTR;
|
||||
SpiFlashOpResult SPI_Encrypt_Write(uint32_t flash_addr, uint32_t* data, uint32_t len) ROMFN_ATTR;
|
||||
SpiFlashOpResult SPIRead(uint32_t src_addr, uint32_t* dest, int32_t len) ROMFN_ATTR;
|
||||
SpiFlashOpResult SPIReadModeCnfig(SpiFlashRdMode mode, bool legacy) ROMFN_ATTR;
|
||||
SpiFlashOpResult SPIMasterReadModeCnfig(SpiFlashRdMode mode) ROMFN_ATTR;
|
||||
SpiFlashOpResult SPIClkConfig(uint8_t freqdiv, uint8_t spi) ROMFN_ATTR;
|
||||
uint16_t SPI_Common_Command(SpiCommonCmd * cmd) ROMFN_ATTR;
|
||||
SpiFlashOpResult SPIUnlock() ROMFN_ATTR;
|
||||
SpiFlashOpResult SPIEraseArea(uint32_t start_addr, uint32_t area_len) ROMFN_ATTR;
|
||||
SpiFlashOpResult SPILock() ROMFN_ATTR;
|
||||
SpiFlashOpResult SPIParamCfg(uint32_t deviceId, uint32_t chip_size, uint32_t block_size, uint32_t sector_size, uint32_t page_size, uint32_t status_mask) ROMFN_ATTR;
|
||||
SpiFlashOpResult SPI_user_command_read(uint32_t * status, uint8_t cmd) ROMFN_ATTR;
|
||||
void spi_cache_sram_init() ROMFN_ATTR;
|
||||
/**
|
||||
* @brief Fix the bug in SPI hardware communication with Flash/Ext-SRAM in High Speed.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param uint8_t spi: 0 for SPI0(Cache Access), 1 for SPI1(Flash read/write).
|
||||
*
|
||||
* @param uint8_t freqdiv: Pll is 80M, 4 for 20M, 3 for 26.7M, 2 for 40M, 1 for 80M.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void spi_dummy_len_fix(uint8_t spi, uint8_t freqdiv);
|
||||
|
||||
//ETS_STATUS ets_unpack_flash_code(uint32_t pos, uint32_t *entry_addr, bool jump, bool sb_need_check, bool config) ROMFN_ATTR;
|
||||
//ETS_STATUS ets_unpack_flash_code_legacy(uint32_t pos, uint32_t *entry_addr, bool jump, bool config) ROMFN_ATTR;
|
||||
/**
|
||||
* @brief Select SPI Flash to QIO mode when WP pad is read from Flash.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param uint8_t wp_gpio_num: WP gpio number.
|
||||
*
|
||||
* @param uint32_t ishspi: 0 for spi, 1 for hspi, flash pad decided by strapping
|
||||
* else, bit[5:0] spiclk, bit[11:6] spiq, bit[17:12] spid, bit[23:18] spics0, bit[29:24] spihd
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void SelectSpiQIO(uint8_t wp_gpio_num, uint32_t ishspi);
|
||||
|
||||
void spi_flash_attach(uint32_t ishspi, bool legacy) ROMFN_ATTR;
|
||||
/**
|
||||
* @brief Set SPI Flash pad drivers.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param uint8_t wp_gpio_num: WP gpio number.
|
||||
*
|
||||
* @param uint32_t ishspi: 0 for spi, 1 for hspi, flash pad decided by strapping
|
||||
* else, bit[5:0] spiclk, bit[11:6] spiq, bit[17:12] spid, bit[23:18] spics0, bit[29:24] spihd
|
||||
*
|
||||
* @param uint8_t *drvs: drvs[0]-bit[3:0] for cpiclk, bit[7:4] for spiq, drvs[1]-bit[3:0] for spid, drvs[1]-bit[7:4] for spid
|
||||
* drvs[2]-bit[3:0] for spihd, drvs[2]-bit[7:4] for spiwp.
|
||||
* Values usually read from falsh by rom code, function usually callde by rom code.
|
||||
* if value with bit(3) set, the value is valid, bit[2:0] is the real value.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void SetSpiDrvs(uint8_t wp_gpio_num, uint32_t ishspi, uint8_t *drvs);
|
||||
|
||||
/**
|
||||
* @brief Select SPI Flash function for pads.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param uint32_t ishspi: 0 for spi, 1 for hspi, flash pad decided by strapping
|
||||
* else, bit[5:0] spiclk, bit[11:6] spiq, bit[17:12] spid, bit[23:18] spics0, bit[29:24] spihd
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void SelectSpiFunction(uint32_t ishspi);
|
||||
|
||||
/**
|
||||
* @brief SPI Flash init, clock divisor is 4, use 1 line Slow read mode.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param uint32_t ishspi: 0 for spi, 1 for hspi, flash pad decided by strapping
|
||||
* else, bit[5:0] spiclk, bit[11:6] spiq, bit[17:12] spid, bit[23:18] spics0, bit[29:24] spihd
|
||||
*
|
||||
* @param uint8_t legacy: In legacy mode, more SPI command is used in line.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void spi_flash_attach(uint32_t ishspi, bool legacy);
|
||||
|
||||
/**
|
||||
* @brief SPI Read Flash status register. We use CMD 0x05.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param SpiFlashChip *spi : The information for Flash, which is exported from ld file.
|
||||
*
|
||||
* @param uint32_t *status : The pointer to which to return the Flash status value.
|
||||
*
|
||||
* @return SPI_FLASH_RESULT_OK : read OK.
|
||||
* SPI_FLASH_RESULT_ERR : read error.
|
||||
* SPI_FLASH_RESULT_TIMEOUT : read timeout.
|
||||
*/
|
||||
SpiFlashOpResult SPI_read_status(SpiFlashChip *spi, uint32_t *status);
|
||||
|
||||
/**
|
||||
* @brief SPI Read Flash status register high 16 bit. We use CMD 0x35.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param SpiFlashChip *spi : The information for Flash, which is exported from ld file.
|
||||
*
|
||||
* @param uint32_t *status : The pointer to which to return the Flash status value.
|
||||
*
|
||||
* @return SPI_FLASH_RESULT_OK : read OK.
|
||||
* SPI_FLASH_RESULT_ERR : read error.
|
||||
* SPI_FLASH_RESULT_TIMEOUT : read timeout.
|
||||
*/
|
||||
SpiFlashOpResult SPI_read_status_high(SpiFlashChip *spi, uint32_t *status);
|
||||
|
||||
/**
|
||||
* @brief Write status to Falsh status register.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param SpiFlashChip *spi : The information for Flash, which is exported from ld file.
|
||||
*
|
||||
* @param uint32_t status_value : Value to .
|
||||
*
|
||||
* @return SPI_FLASH_RESULT_OK : write OK.
|
||||
* SPI_FLASH_RESULT_ERR : write error.
|
||||
* SPI_FLASH_RESULT_TIMEOUT : write timeout.
|
||||
*/
|
||||
SpiFlashOpResult SPI_write_status(SpiFlashChip *spi, uint32_t status_value);
|
||||
|
||||
/**
|
||||
* @brief Use a command to Read Flash status register.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param SpiFlashChip *spi : The information for Flash, which is exported from ld file.
|
||||
*
|
||||
* @param uint32_t*status : The pointer to which to return the Flash status value.
|
||||
*
|
||||
* @return SPI_FLASH_RESULT_OK : read OK.
|
||||
* SPI_FLASH_RESULT_ERR : read error.
|
||||
* SPI_FLASH_RESULT_TIMEOUT : read timeout.
|
||||
*/
|
||||
SpiFlashOpResult SPI_user_command_read(uint32_t *status, uint8_t cmd);
|
||||
|
||||
/**
|
||||
* @brief Config SPI Flash read mode when init.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param SpiFlashRdMode mode : QIO/QOUT/DIO/DOUT/FastRD/SlowRD.
|
||||
*
|
||||
* @param uint8_t legacy: In legacy mode, more SPI command is used in line.
|
||||
*
|
||||
* @return SPI_FLASH_RESULT_OK : config OK.
|
||||
* SPI_FLASH_RESULT_ERR : config error.
|
||||
* SPI_FLASH_RESULT_TIMEOUT : config timeout.
|
||||
*/
|
||||
SpiFlashOpResult SPIReadModeCnfig(SpiFlashRdMode mode, bool legacy);
|
||||
|
||||
/**
|
||||
* @brief Config SPI Flash read mode when Flash is running in some mode.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param SpiFlashRdMode mode : QIO/QOUT/DIO/DOUT/FastRD/SlowRD.
|
||||
*
|
||||
* @return SPI_FLASH_RESULT_OK : config OK.
|
||||
* SPI_FLASH_RESULT_ERR : config error.
|
||||
* SPI_FLASH_RESULT_TIMEOUT : config timeout.
|
||||
*/
|
||||
SpiFlashOpResult SPIMasterReadModeCnfig(SpiFlashRdMode mode);
|
||||
|
||||
/**
|
||||
* @brief Config SPI Flash clock divisor.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param uint8_t freqdiv: clock divisor.
|
||||
*
|
||||
* @param uint8_t spi: 0 for SPI0, 1 for SPI1.
|
||||
*
|
||||
* @return SPI_FLASH_RESULT_OK : config OK.
|
||||
* SPI_FLASH_RESULT_ERR : config error.
|
||||
* SPI_FLASH_RESULT_TIMEOUT : config timeout.
|
||||
*/
|
||||
SpiFlashOpResult SPIClkConfig(uint8_t freqdiv, uint8_t spi);
|
||||
|
||||
/**
|
||||
* @brief Send CommonCmd to Flash so that is can go into QIO mode, some Flash use different CMD.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param SpiCommonCmd *cmd : A struct to show the action of a command.
|
||||
*
|
||||
* @return uint16_t 0 : do not send command any more.
|
||||
* 1 : go to the next command.
|
||||
* n > 1 : skip (n - 1) commands.
|
||||
*/
|
||||
uint16_t SPI_Common_Command(SpiCommonCmd *cmd);
|
||||
|
||||
/**
|
||||
* @brief Unlock SPI write protect.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return SPI_FLASH_RESULT_OK : Unlock OK.
|
||||
* SPI_FLASH_RESULT_ERR : Unlock error.
|
||||
* SPI_FLASH_RESULT_TIMEOUT : Unlock timeout.
|
||||
*/
|
||||
SpiFlashOpResult SPIUnlock(void);
|
||||
|
||||
/**
|
||||
* @brief SPI write protect.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return SPI_FLASH_RESULT_OK : Lock OK.
|
||||
* SPI_FLASH_RESULT_ERR : Lock error.
|
||||
* SPI_FLASH_RESULT_TIMEOUT : Lock timeout.
|
||||
*/
|
||||
SpiFlashOpResult SPILock(void);
|
||||
|
||||
/**
|
||||
* @brief Update SPI Flash parameter.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param uint32_t deviceId : Device ID read from SPI, the low 32 bit.
|
||||
*
|
||||
* @param uint32_t chip_size : The Flash size.
|
||||
*
|
||||
* @param uint32_t block_size : The Flash block size.
|
||||
*
|
||||
* @param uint32_t sector_size : The Flash sector size.
|
||||
*
|
||||
* @param uint32_t page_size : The Flash page size.
|
||||
*
|
||||
* @param uint32_t status_mask : The Mask used when read status from Flash(use single CMD).
|
||||
*
|
||||
* @return SPI_FLASH_RESULT_OK : Update OK.
|
||||
* SPI_FLASH_RESULT_ERR : Update error.
|
||||
* SPI_FLASH_RESULT_TIMEOUT : Update timeout.
|
||||
*/
|
||||
SpiFlashOpResult SPIParamCfg(uint32_t deviceId, uint32_t chip_size, uint32_t block_size, uint32_t sector_size, uint32_t page_size, uint32_t status_mask);
|
||||
|
||||
/**
|
||||
* @brief Erase whole flash chip.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return SPI_FLASH_RESULT_OK : Erase OK.
|
||||
* SPI_FLASH_RESULT_ERR : Erase error.
|
||||
* SPI_FLASH_RESULT_TIMEOUT : Erase timeout.
|
||||
*/
|
||||
SpiFlashOpResult SPIEraseChip(void);
|
||||
|
||||
/**
|
||||
* @brief Erase a block of flash.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param uint32_t block_num : Which block to erase.
|
||||
*
|
||||
* @return SPI_FLASH_RESULT_OK : Erase OK.
|
||||
* SPI_FLASH_RESULT_ERR : Erase error.
|
||||
* SPI_FLASH_RESULT_TIMEOUT : Erase timeout.
|
||||
*/
|
||||
SpiFlashOpResult SPIEraseBlock(uint32_t block_num);
|
||||
|
||||
/**
|
||||
* @brief Erase a sector of flash.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param uint32_t sector_num : Which sector to erase.
|
||||
*
|
||||
* @return SPI_FLASH_RESULT_OK : Erase OK.
|
||||
* SPI_FLASH_RESULT_ERR : Erase error.
|
||||
* SPI_FLASH_RESULT_TIMEOUT : Erase timeout.
|
||||
*/
|
||||
SpiFlashOpResult SPIEraseSector(uint32_t sector_num);
|
||||
|
||||
/**
|
||||
* @brief Erase some sectors.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param uint32_t start_addr : Start addr to erase, should be sector aligned.
|
||||
*
|
||||
* @param uint32_t area_len : Length to erase, should be sector aligned.
|
||||
*
|
||||
* @return SPI_FLASH_RESULT_OK : Erase OK.
|
||||
* SPI_FLASH_RESULT_ERR : Erase error.
|
||||
* SPI_FLASH_RESULT_TIMEOUT : Erase timeout.
|
||||
*/
|
||||
SpiFlashOpResult SPIEraseArea(uint32_t start_addr, uint32_t area_len);
|
||||
|
||||
/**
|
||||
* @brief Write Data to Flash, you should Erase it yourself if need.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param uint32_t dest_addr : Address to write, should be 4 bytes aligned.
|
||||
*
|
||||
* @param const uint32_t *src : The pointer to data which is to write.
|
||||
*
|
||||
* @param uint32_t len : Length to write, should be 4 bytes aligned.
|
||||
*
|
||||
* @return SPI_FLASH_RESULT_OK : Write OK.
|
||||
* SPI_FLASH_RESULT_ERR : Write error.
|
||||
* SPI_FLASH_RESULT_TIMEOUT : Write timeout.
|
||||
*/
|
||||
SpiFlashOpResult SPIWrite(uint32_t dest_addr, const uint32_t *src, int32_t len);
|
||||
|
||||
/**
|
||||
* @brief Read Data from Flash, you should Erase it yourself if need.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param uint32_t src_addr : Address to read, should be 4 bytes aligned.
|
||||
*
|
||||
* @param uint32_t *dest : The buf to read the data.
|
||||
*
|
||||
* @param uint32_t len : Length to read, should be 4 bytes aligned.
|
||||
*
|
||||
* @return SPI_FLASH_RESULT_OK : Read OK.
|
||||
* SPI_FLASH_RESULT_ERR : Read error.
|
||||
* SPI_FLASH_RESULT_TIMEOUT : Read timeout.
|
||||
*/
|
||||
SpiFlashOpResult SPIRead(uint32_t src_addr, uint32_t *dest, int32_t len);
|
||||
|
||||
/**
|
||||
* @brief SPI1 go into encrypto mode.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void SPI_Write_Encrypt_Enable(void);
|
||||
|
||||
/**
|
||||
* @brief Prepare 32 Bytes data to encrpto writing, you should Erase it yourself if need.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param uint32_t flash_addr : Address to write, should be 32 bytes aligned.
|
||||
*
|
||||
* @param uint32_t *data : The pointer to data which is to write.
|
||||
*
|
||||
* @return SPI_FLASH_RESULT_OK : Prepare OK.
|
||||
* SPI_FLASH_RESULT_ERR : Prepare error.
|
||||
* SPI_FLASH_RESULT_TIMEOUT : Prepare timeout.
|
||||
*/
|
||||
SpiFlashOpResult SPI_Prepare_Encrypt_Data(uint32_t flash_addr, uint32_t *data);
|
||||
|
||||
/**
|
||||
* @brief SPI1 go out of encrypto mode.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void SPI_Write_Encrypt_Disable(void);
|
||||
|
||||
/**
|
||||
* @brief Encrpto writing data to flash, you should Erase it yourself if need.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param uint32_t flash_addr : Address to write, should be 32 bytes aligned.
|
||||
*
|
||||
* @param uint32_t *data : The pointer to data which is to write.
|
||||
*
|
||||
* @param uint32_t len : Length to write, should be 32 bytes aligned.
|
||||
*
|
||||
* @return SPI_FLASH_RESULT_OK : Encrypto write OK.
|
||||
* SPI_FLASH_RESULT_ERR : Encrypto write error.
|
||||
* SPI_FLASH_RESULT_TIMEOUT : Encrypto write timeout.
|
||||
*/
|
||||
SpiFlashOpResult SPI_Encrypt_Write(uint32_t flash_addr, uint32_t *data, uint32_t len);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -1,85 +0,0 @@
|
||||
// Copyright 2011-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _ROM_SSC_H_
|
||||
#define _ROM_SSC_H_
|
||||
|
||||
#include "esp_types.h"
|
||||
|
||||
#include "esp_attr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct cmd_s {
|
||||
char *cmd_str;
|
||||
#define CMD_T_ASYNC 0x01
|
||||
#define CMD_T_SYNC 0x02
|
||||
uint8_t flag;
|
||||
uint8_t id;
|
||||
void (* cmd_func)(void);
|
||||
void (* cmd_callback)(void *arg);
|
||||
} ssc_cmd_t;
|
||||
|
||||
#define ssc_printf ets_printf
|
||||
#define SSC_CMD_N 10 //since the command not added in ssc_cmd.c
|
||||
#define MAX_LINE_N 40
|
||||
#define PROMPT ":>"
|
||||
#define SSC_EVT_N 4
|
||||
|
||||
|
||||
#define SSC_PRIO 30
|
||||
enum {
|
||||
CMD_SET_SSID = 0,
|
||||
CMD_SCAN,
|
||||
CMD_CONNECT,
|
||||
CMD_DISCONNECT,
|
||||
CMD_SET_MACADDR,
|
||||
CMD_PING,
|
||||
CMD_PING_COUNT,
|
||||
CMD_PING_LENGTH,
|
||||
CMD_SET_IP,
|
||||
// CMD_RD_I2C,
|
||||
// CMD_SET_NULL, it's just for solving the old rom bug
|
||||
// CMD_SET_I2C,
|
||||
// CMD_RD_I2CM,
|
||||
// CMD_SET_I2CM,
|
||||
// CMD_SET_PBUS,
|
||||
// CMD_SET_TXTONE,
|
||||
// CMD_SET_STOPTONE,
|
||||
CMD_END,
|
||||
};
|
||||
|
||||
enum {
|
||||
SIG_SSC_RUNCMD,
|
||||
SIG_SSC_CMDDONE,
|
||||
SIG_SSC_RESTART,
|
||||
SIG_SSC_UART_RX_CHAR,
|
||||
};
|
||||
|
||||
void ssc_attach(void) ROMFN_ATTR;
|
||||
void ssc_cmd_done(int cmd_id, STATUS status) ROMFN_ATTR;
|
||||
int ssc_param_len(void) ROMFN_ATTR;
|
||||
char * ssc_param_str(void) ROMFN_ATTR;
|
||||
void ssc_register(ssc_cmd_t *cmdset, uint8_t cmdnum, void (* help)(void)) ROMFN_ATTR;
|
||||
|
||||
extern ssc_cmd_t sscCmdSet[];
|
||||
void ssc_help(void);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _ROM_SSC_H_ */
|
282
components/esp32/include/rom/uart.h
Executable file → Normal file
282
components/esp32/include/rom/uart.h
Executable file → Normal file
@ -22,6 +22,14 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup uart_apis, uart configuration and communication related apis
|
||||
* @brief uart apis
|
||||
*/
|
||||
|
||||
/** @addtogroup uart_apis
|
||||
* @{
|
||||
*/
|
||||
|
||||
#define RX_BUFF_SIZE 0x100
|
||||
#define TX_BUFF_SIZE 100
|
||||
|
||||
@ -52,9 +60,9 @@ extern "C" {
|
||||
#define UART_RCV_ERR_FLAG BIT7
|
||||
|
||||
//send and receive message frame head
|
||||
#define FRAME_FLAG 0x7E
|
||||
#define FRAME_FLAG 0x7E
|
||||
|
||||
typedef enum{
|
||||
typedef enum {
|
||||
UART_LINE_STATUS_INT_FLAG = 0x06,
|
||||
UART_RCV_FIFO_INT_FLAG = 0x04,
|
||||
UART_RCV_TMOUT_INT_FLAG = 0x0C,
|
||||
@ -82,9 +90,9 @@ typedef enum {
|
||||
} UartStopBitsNum;
|
||||
|
||||
typedef enum {
|
||||
NONE_BITS = 0,
|
||||
ODD_BITS = 2,
|
||||
EVEN_BITS = 3
|
||||
NONE_BITS = 0,
|
||||
ODD_BITS = 2,
|
||||
EVEN_BITS = 3
|
||||
|
||||
} UartParityMode;
|
||||
|
||||
@ -113,7 +121,7 @@ typedef enum {
|
||||
typedef enum {
|
||||
EMPTY,
|
||||
UNDER_WRITE,
|
||||
WRITE_OVER
|
||||
WRITE_OVER
|
||||
} RcvMsgBuffState;
|
||||
|
||||
typedef struct {
|
||||
@ -121,9 +129,9 @@ typedef struct {
|
||||
uint8_t *pRcvMsgBuff;
|
||||
uint8_t *pWritePos;
|
||||
uint8_t *pReadPos;
|
||||
uint8_t TrigLvl; //JLU: may need to pad
|
||||
uint8_t TrigLvl;
|
||||
RcvMsgBuffState BuffState;
|
||||
}RcvMsgBuff;
|
||||
} RcvMsgBuff;
|
||||
|
||||
typedef struct {
|
||||
uint32_t TrxBuffSize;
|
||||
@ -138,7 +146,7 @@ typedef enum {
|
||||
RCV_ESC_CHAR,
|
||||
} RcvMsgState;
|
||||
|
||||
typedef struct{
|
||||
typedef struct {
|
||||
UartBautRate baut_rate;
|
||||
UartBitsNum4Char data_bits;
|
||||
UartExistParity exist_parity;
|
||||
@ -153,33 +161,249 @@ typedef struct{
|
||||
int received;
|
||||
} UartDevice;
|
||||
|
||||
void Uart_Init(uint8_t uart_no, uint32_t clock) ROMFN_ATTR;
|
||||
STATUS UartTxString(uint8_t* pString) ROMFN_ATTR;
|
||||
STATUS UartRxString(uint8_t* pString, uint8_t MaxStrlen) ROMFN_ATTR;
|
||||
/**
|
||||
* @brief Init uart device struct value and reset uart0/uart1 rx.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void uartAttach(void);
|
||||
|
||||
STATUS uart_tx_one_char(uint8_t TxChar) ROMFN_ATTR;//for print
|
||||
STATUS uart_tx_one_char2(uint8_t TxChar) ROMFN_ATTR;//for send message
|
||||
STATUS uart_rx_one_char(uint8_t* pRxChar) ROMFN_ATTR;
|
||||
char uart_rx_one_char_block(void) ROMFN_ATTR;
|
||||
void uart_rx_intr_handler(void * para) ROMFN_ATTR;
|
||||
STATUS uart_rx_readbuff( RcvMsgBuff* pRxBuff, uint8_t* pRxByte) ROMFN_ATTR;
|
||||
STATUS UartGetCmdLn(uint8_t * pCmdLn) ROMFN_ATTR;
|
||||
UartDevice * GetUartDevice() ROMFN_ATTR;
|
||||
/**
|
||||
* @brief Init uart0 or uart1 for UART download booting mode.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param uint8_t uart_no : 0 for UART0, else for UART1.
|
||||
*
|
||||
* @param uint32_t clock : clock used by uart module, to adjust baudrate.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void Uart_Init(uint8_t uart_no, uint32_t clock);
|
||||
|
||||
void uartToggleInterrupt(bool en) ROMFN_ATTR;
|
||||
/**
|
||||
* @brief Modify uart baudrate.
|
||||
* This function will reset RX/TX fifo for uart.
|
||||
*
|
||||
* @param uint8_t uart_no : 0 for UART0, 1 for UART1.
|
||||
*
|
||||
* @param uint32_t DivLatchValue : (clock << 4)/baudrate.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void uart_div_modify(uint8_t uart_no, uint32_t DivLatchValue);
|
||||
|
||||
STATUS SendMsg(uint8_t *pData, uint16_t DataLen) ROMFN_ATTR;
|
||||
/**
|
||||
* @brief Init uart0 or uart1 for UART download booting mode.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param uint8_t uart_no : 0 for UART0, 1 for UART1.
|
||||
*
|
||||
* @param uint8_t is_sync : 0, only one UART module, easy to detect, wait until detected;
|
||||
* 1, two UART modules, hard to detect, detect and return.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
int uart_baudrate_detect(uint8_t uart_no, uint8_t is_sync);
|
||||
|
||||
STATUS RcvMsg(uint8_t *pData, uint16_t MaxDataLen, uint8_t is_sync) ROMFN_ATTR;
|
||||
/**
|
||||
* @brief Switch printf channel of uart_tx_one_char.
|
||||
* Please do not call this function when printf.
|
||||
*
|
||||
* @param uint8_t uart_no : 0 for UART0, 1 for UART1.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void uart_tx_switch(uint8_t uart_no);
|
||||
|
||||
/**
|
||||
* @brief Switch message exchange channel for UART download booting.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param uint8_t uart_no : 0 for UART0, 1 for UART1.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void uart_buff_switch(uint8_t uart_no);
|
||||
|
||||
/**
|
||||
* @brief Output a char to printf channel, wait until fifo not full.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return OK.
|
||||
*/
|
||||
STATUS uart_tx_one_char(uint8_t TxChar);
|
||||
|
||||
/**
|
||||
* @brief Output a char to message exchange channel, wait until fifo not full.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return OK.
|
||||
*/
|
||||
STATUS uart_tx_one_char2(uint8_t TxChar);//for send message
|
||||
|
||||
/**
|
||||
* @brief Wait until uart tx full empty.
|
||||
*
|
||||
* @param uint8_t uart_no : 0 for UART0, 1 for UART1.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void uart_tx_flush(uint8_t uart_no);
|
||||
|
||||
/**
|
||||
* @brief Wait until uart tx full empty and the last char send ok.
|
||||
*
|
||||
* @param uint8_t uart_no : 0 for UART0, 1 for UART1.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void uart_tx_wait_idle(uint8_t uart_no);
|
||||
|
||||
/**
|
||||
* @brief Get an input char from message channel.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param uint8_t *pRxChar : the pointer to store the char.
|
||||
*
|
||||
* @return OK for successful.
|
||||
* FAIL for failed.
|
||||
*/
|
||||
STATUS uart_rx_one_char(uint8_t *pRxChar);
|
||||
|
||||
/**
|
||||
* @brief Get an input char to message channel, wait until successful.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return char : input char value.
|
||||
*/
|
||||
char uart_rx_one_char_block(void);
|
||||
|
||||
/**
|
||||
* @brief Get an input string line from message channel.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param uint8_t *pString : the pointer to store the string.
|
||||
*
|
||||
* @param uint8_t MaxStrlen : the max string length, incude '\0'.
|
||||
*
|
||||
* @return OK.
|
||||
*/
|
||||
STATUS UartRxString(uint8_t *pString, uint8_t MaxStrlen);
|
||||
|
||||
/**
|
||||
* @brief Process uart recevied information in the interrupt handler.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param void *para : the message receive buffer.
|
||||
*
|
||||
* @return None
|
||||
*/
|
||||
void uart_rx_intr_handler(void *para);
|
||||
|
||||
/**
|
||||
* @brief Get an char from receive buffer.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param RcvMsgBuff *pRxBuff : the pointer to the struct that include receive buffer.
|
||||
*
|
||||
* @param uint8_t *pRxByte : the pointer to store the char.
|
||||
*
|
||||
* @return OK for successful.
|
||||
* FAIL for failed.
|
||||
*/
|
||||
STATUS uart_rx_readbuff( RcvMsgBuff *pRxBuff, uint8_t *pRxByte);
|
||||
|
||||
/**
|
||||
* @brief Get all chars from receive buffer.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param uint8_t *pCmdLn : the pointer to store the string.
|
||||
*
|
||||
* @return OK for successful.
|
||||
* FAIL for failed.
|
||||
*/
|
||||
STATUS UartGetCmdLn(uint8_t *pCmdLn);
|
||||
|
||||
/**
|
||||
* @brief Get uart configuration struct.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param None
|
||||
*
|
||||
* @return UartDevice * : uart configuration struct pointer.
|
||||
*/
|
||||
UartDevice *GetUartDevice(void);
|
||||
|
||||
/**
|
||||
* @brief Send an packet to download tool, with SLIP escaping.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param uint8_t *p : the pointer to output string.
|
||||
*
|
||||
* @param int len : the string length.
|
||||
*
|
||||
* @return None.
|
||||
*/
|
||||
void send_packet(uint8_t *p, int len);
|
||||
|
||||
/**
|
||||
* @brief Receive an packet from download tool, with SLIP escaping.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param uint8_t *p : the pointer to input string.
|
||||
*
|
||||
* @param int len : If string length > len, the string will be truncated.
|
||||
*
|
||||
* @param uint8_t is_sync : 0, only one UART module;
|
||||
* 1, two UART modules.
|
||||
*
|
||||
* @return int : the length of the string.
|
||||
*/
|
||||
int recv_packet(uint8_t *p, int len, uint8_t is_sync);
|
||||
|
||||
/**
|
||||
* @brief Send an packet to download tool, with SLIP escaping.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param uint8_t *pData : the pointer to input string.
|
||||
*
|
||||
* @param uint16_t DataLen : the string length.
|
||||
*
|
||||
* @return OK for successful.
|
||||
* FAIL for failed.
|
||||
*/
|
||||
STATUS SendMsg(uint8_t *pData, uint16_t DataLen);
|
||||
|
||||
/**
|
||||
* @brief Receive an packet from download tool, with SLIP escaping.
|
||||
* Please do not call this function in SDK.
|
||||
*
|
||||
* @param uint8_t *pData : the pointer to input string.
|
||||
*
|
||||
* @param uint16_t MaxDataLen : If string length > MaxDataLen, the string will be truncated.
|
||||
*
|
||||
* @param uint8_t is_sync : 0, only one UART module;
|
||||
* 1, two UART modules.
|
||||
*
|
||||
* @return OK for successful.
|
||||
* FAIL for failed.
|
||||
*/
|
||||
STATUS RcvMsg(uint8_t *pData, uint16_t MaxDataLen, uint8_t is_sync);
|
||||
|
||||
void uartAttach() ROMFN_ATTR;
|
||||
void uart_div_modify(uint8_t uart_no, uint32_t DivLatchValue) ROMFN_ATTR;
|
||||
int uart_baudrate_detect(uint8_t uart_no, uint8_t is_sync) ROMFN_ATTR;
|
||||
void uart_buff_switch(uint8_t uart_no) ROMFN_ATTR;
|
||||
void uart_tx_flush(uint8_t uart_no) ROMFN_ATTR;
|
||||
void uart_tx_wait_idle(uint8_t uart_no) ROMFN_ATTR;
|
||||
extern UartDevice UartDev;
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -1,40 +0,0 @@
|
||||
// Copyright 2010-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef _ROM_WDT_H_
|
||||
#define _ROM_WDT_H_
|
||||
|
||||
#include "soc.h"
|
||||
#include "ets_sys.h"
|
||||
|
||||
#define WDT_RESET_VALUE 0x73
|
||||
#define WDT_RESET_LEN 7 //real time: (1<<(WDT_RESET_LEN+1))*pclk
|
||||
#define WDT_CONTROL_ENABLED BIT0
|
||||
#define WDT_MODE_SET(v) (v)
|
||||
#define WDT_TARGET_SET(v) (v)
|
||||
#define WDT_ADDRESS 0
|
||||
|
||||
#define SEC_TO_WDT_TICK(s) (s * WDT_CLK_FREQ) //it's Pclk clock,44MHz
|
||||
|
||||
typedef enum{
|
||||
NEXT_OVERFLOW_RESET = 0,
|
||||
NEXT_OVERFLOW_NO_RESET = 1,
|
||||
EACH_OVERFLOW_RESET = 2,
|
||||
} WDT_RESP_MODE;
|
||||
|
||||
#define WDT_DEFAULT_FEED_INTERVAL WDT_INTERVAL_SIX_SEC /* 6 seconds */
|
||||
#define WDT_DEFAULT_EXPIRE_INTERVAL WDT_INTERVAL_TWELVE_SEC /* 12 seconds */
|
||||
|
||||
#endif /* _ROM_WDT_H_ */
|
||||
|
@ -80,21 +80,24 @@
|
||||
#define FUNC_GPIO33_GPIO33_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO25_U (DR_REG_IO_MUX_BASE +0x24)
|
||||
#define FUNC_GPIO25_EMAC_RXD0 5
|
||||
#define FUNC_GPIO25_GPIO25 2
|
||||
#define FUNC_GPIO25_GPIO25_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO26_U (DR_REG_IO_MUX_BASE +0x28)
|
||||
#define FUNC_GPIO26_EMAC_RXD1 5
|
||||
#define FUNC_GPIO26_GPIO26 2
|
||||
#define FUNC_GPIO26_GPIO26_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO27_U (DR_REG_IO_MUX_BASE +0x2c)
|
||||
#define FUNC_GPIO27_EMAC_RXD2 5
|
||||
#define FUNC_GPIO27_EMAC_RX_DV 5
|
||||
#define FUNC_GPIO27_GPIO27 2
|
||||
#define FUNC_GPIO27_GPIO27_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_MTMS_U (DR_REG_IO_MUX_BASE +0x30)
|
||||
#define FUNC_MTMS_EMAC_TXD2 5
|
||||
#define FUNC_MTMS_SD_CLK 4
|
||||
#define FUNC_MTMS_HS2_CLk 3
|
||||
#define FUNC_MTMS_GPIO14 2
|
||||
#define FUNC_MTMS_HSPICLK 1
|
||||
#define FUNC_MTMS_MTMS 0
|
||||
@ -102,6 +105,7 @@
|
||||
#define PERIPHS_IO_MUX_MTDI_U (DR_REG_IO_MUX_BASE +0x34)
|
||||
#define FUNC_MTDI_EMAC_TXD3 5
|
||||
#define FUNC_MTDI_SD_DATA2 4
|
||||
#define FUNC_MTDI_HS2_DATA2 3
|
||||
#define FUNC_MTDI_GPIO12 2
|
||||
#define FUNC_MTDI_HSPIQ 1
|
||||
#define FUNC_MTDI_MTDI 0
|
||||
@ -109,7 +113,7 @@
|
||||
#define PERIPHS_IO_MUX_MTCK_U (DR_REG_IO_MUX_BASE +0x38)
|
||||
#define FUNC_MTCK_EMAC_RX_ER 5
|
||||
#define FUNC_MTCK_SD_DATA3 4
|
||||
#define FUNC_MTCK_U0CTS 3
|
||||
#define FUNC_MTCK_HS2_DATA3 3
|
||||
#define FUNC_MTCK_GPIO13 2
|
||||
#define FUNC_MTCK_HSPID 1
|
||||
#define FUNC_MTCK_MTCK 0
|
||||
@ -117,21 +121,20 @@
|
||||
#define PERIPHS_IO_MUX_MTDO_U (DR_REG_IO_MUX_BASE +0x3c)
|
||||
#define FUNC_MTDO_EMAC_RXD3 5
|
||||
#define FUNC_MTDO_SD_CMD 4
|
||||
#define FUNC_MTDO_U0RTS 3
|
||||
#define FUNC_MTDO_HS2_CMD 3
|
||||
#define FUNC_MTDO_GPIO15 2
|
||||
#define FUNC_MTDO_HSPICS0 1
|
||||
#define FUNC_MTDO_MTDO 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO2_U (DR_REG_IO_MUX_BASE +0x40)
|
||||
#define FUNC_GPIO2_EMAC_RX_DV 5
|
||||
#define FUNC_GPIO2_SD_DATA0 4
|
||||
#define FUNC_GPIO2_HS2_DATA0 3
|
||||
#define FUNC_GPIO2_GPIO2 2
|
||||
#define FUNC_GPIO2_HSPIWP 1
|
||||
#define FUNC_GPIO2_GPIO2_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO0_U (DR_REG_IO_MUX_BASE +0x44)
|
||||
#define FUNC_GPIO0_EMAC_TX_CLK 5
|
||||
#define FUNC_GPIO0_HS2_CMD 3
|
||||
#define FUNC_GPIO0_GPIO0 2
|
||||
#define FUNC_GPIO0_CLK_OUT1 1
|
||||
#define FUNC_GPIO0_GPIO0_0 0
|
||||
@ -139,6 +142,7 @@
|
||||
#define PERIPHS_IO_MUX_GPIO4_U (DR_REG_IO_MUX_BASE +0x48)
|
||||
#define FUNC_GPIO4_EMAC_TX_ER 5
|
||||
#define FUNC_GPIO4_SD_DATA1 4
|
||||
#define FUNC_GPIO4_HS2_DATA1 3
|
||||
#define FUNC_GPIO4_GPIO4 2
|
||||
#define FUNC_GPIO4_HSPIHD 1
|
||||
#define FUNC_GPIO4_GPIO4_0 0
|
||||
@ -207,15 +211,14 @@
|
||||
#define FUNC_GPIO5_GPIO5_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO18_U (DR_REG_IO_MUX_BASE +0x70)
|
||||
#define FUNC_GPIO18_EMAC_TXD0 5
|
||||
#define FUNC_GPIO18_HS1_DATA7 3
|
||||
#define FUNC_GPIO18_GPIO18 2
|
||||
#define FUNC_GPIO18_VSPICLK 1
|
||||
#define FUNC_GPIO18_GPIO18_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO19_U (DR_REG_IO_MUX_BASE +0x74)
|
||||
#define FUNC_GPIO19_EMAC_TXD1 5
|
||||
#define FUNC_GPIO19_HS2_DATA2 3
|
||||
#define FUNC_GPIO19_EMAC_TXD0 5
|
||||
#define FUNC_GPIO19_U0CTS 3
|
||||
#define FUNC_GPIO19_GPIO19 2
|
||||
#define FUNC_GPIO19_VSPIQ 1
|
||||
#define FUNC_GPIO19_GPIO19_0 0
|
||||
@ -225,33 +228,30 @@
|
||||
#define FUNC_GPIO20_GPIO20_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO21_U (DR_REG_IO_MUX_BASE +0x7c)
|
||||
#define FUNC_GPIO21_EMAC_RXD0 5
|
||||
#define FUNC_GPIO21_HS2_DATA3 3
|
||||
#define FUNC_GPIO21_EMAC_TX_EN 5
|
||||
#define FUNC_GPIO21_GPIO21 2
|
||||
#define FUNC_GPIO21_VSPIHD 1
|
||||
#define FUNC_GPIO21_GPIO21_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO22_U (DR_REG_IO_MUX_BASE +0x80)
|
||||
#define FUNC_GPIO22_EMAC_RXD1 5
|
||||
#define FUNC_GPIO22_HS2_CLK 3
|
||||
#define FUNC_GPIO22_EMAC_TXD1 5
|
||||
#define FUNC_GPIO22_U0RTS 3
|
||||
#define FUNC_GPIO22_GPIO22 2
|
||||
#define FUNC_GPIO22_VSPIWP 1
|
||||
#define FUNC_GPIO22_GPIO22_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_U0RXD_U (DR_REG_IO_MUX_BASE +0x84)
|
||||
#define FUNC_U0RXD_HS2_DATA0 3
|
||||
#define FUNC_U0RXD_GPIO3 2
|
||||
#define FUNC_U0RXD_CLK_OUT2 1
|
||||
#define FUNC_U0RXD_U0RXD 0
|
||||
|
||||
#define PERIPHS_IO_MUX_U0TXD_U (DR_REG_IO_MUX_BASE +0x88)
|
||||
#define FUNC_U0TXD_HS2_DATA1 3
|
||||
#define FUNC_U0TXD_EMAC_RXD2 3
|
||||
#define FUNC_U0TXD_GPIO1 2
|
||||
#define FUNC_U0TXD_CLK_OUT3 1
|
||||
#define FUNC_U0TXD_U0TXD 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO23_U (DR_REG_IO_MUX_BASE +0x8c)
|
||||
#define FUNC_GPIO23_EMAC_TX_EN 5
|
||||
#define FUNC_GPIO23_HS1_STROBE 3
|
||||
#define FUNC_GPIO23_GPIO23 2
|
||||
#define FUNC_GPIO23_VSPID 1
|
||||
|
@ -58,98 +58,93 @@
|
||||
|
||||
#define BIT(nr) (1UL << (nr))
|
||||
|
||||
//write value to register
|
||||
#define REG_WRITE(_r, _v) (*(volatile uint32_t *)(_r)) = (_v)
|
||||
|
||||
//read value from register
|
||||
#define REG_READ(_r) (*(volatile uint32_t *)(_r))
|
||||
|
||||
//get bit or get bits from register
|
||||
#define REG_GET_BIT(_r, _b) (*(volatile uint32_t*)(_r) & (_b))
|
||||
|
||||
//set bit or set bits to register
|
||||
#define REG_SET_BIT(_r, _b) (*(volatile uint32_t*)(_r) |= (_b))
|
||||
|
||||
//clear bit or clear bits of register
|
||||
#define REG_CLR_BIT(_r, _b) (*(volatile uint32_t*)(_r) &= ~(_b))
|
||||
|
||||
//set bits of register controlled by mask
|
||||
#define REG_SET_BITS(_r, _b, _m) (*(volatile uint32_t*)(_r) = (*(volatile uint32_t*)(_r) & ~(_m)) | ((_b) & (_m)))
|
||||
#define VALUE_GET_FIELD(_r, _f) (((_r) >> (_f##_S)) & (_f))
|
||||
#define VALUE_GET_FIELD2(_r, _f) (((_r) & (_f))>> (_f##_S))
|
||||
#define VALUE_SET_FIELD(_r, _f, _v) ((_r)=(((_r) & ~((_f) << (_f##_S)))|((_v)<<(_f##_S))))
|
||||
#define VALUE_SET_FIELD2(_r, _f, _v) ((_r)=(((_r) & ~(_f))|((_v)<<(_f##_S))))
|
||||
#define FIELD_TO_VALUE(_f, _v) (((_v)&(_f))<<_f##_S)
|
||||
#define FIELD_TO_VALUE2(_f, _v) (((_v)<<_f##_S) & (_f))
|
||||
|
||||
//get field from register, used when _f is not left shifted by _f##_S
|
||||
#define REG_GET_FIELD(_r, _f) ((REG_READ(_r) >> (_f##_S)) & (_f))
|
||||
|
||||
//set field to register, used when _f is not left shifted by _f##_S
|
||||
#define REG_SET_FIELD(_r, _f, _v) (REG_WRITE((_r),((REG_READ(_r) & ~((_f) << (_f##_S)))|(((_v) & (_f))<<(_f##_S)))))
|
||||
|
||||
//get field value from a variable, used when _f is not left shifted by _f##_S
|
||||
#define VALUE_GET_FIELD(_r, _f) (((_r) >> (_f##_S)) & (_f))
|
||||
|
||||
//get field value from a variable, used when _f is left shifted by _f##_S
|
||||
#define VALUE_GET_FIELD2(_r, _f) (((_r) & (_f))>> (_f##_S))
|
||||
|
||||
//set field value to a variable, used when _f is not left shifted by _f##_S
|
||||
#define VALUE_SET_FIELD(_r, _f, _v) ((_r)=(((_r) & ~((_f) << (_f##_S)))|((_v)<<(_f##_S))))
|
||||
|
||||
//set field value to a variable, used when _f is left shifted by _f##_S
|
||||
#define VALUE_SET_FIELD2(_r, _f, _v) ((_r)=(((_r) & ~(_f))|((_v)<<(_f##_S))))
|
||||
|
||||
//generate a value from a field value, used when _f is not left shifted by _f##_S
|
||||
#define FIELD_TO_VALUE(_f, _v) (((_v)&(_f))<<_f##_S)
|
||||
|
||||
//generate a value from a field value, used when _f is left shifted by _f##_S
|
||||
#define FIELD_TO_VALUE2(_f, _v) (((_v)<<_f##_S) & (_f))
|
||||
|
||||
//read value from register
|
||||
#define READ_PERI_REG(addr) (*((volatile uint32_t *)ETS_UNCACHED_ADDR(addr)))
|
||||
|
||||
//write value to register
|
||||
#define WRITE_PERI_REG(addr, val) (*((volatile uint32_t *)ETS_UNCACHED_ADDR(addr))) = (uint32_t)(val)
|
||||
|
||||
//clear bits of register controlled by mask
|
||||
#define CLEAR_PERI_REG_MASK(reg, mask) WRITE_PERI_REG((reg), (READ_PERI_REG(reg)&(~(mask))))
|
||||
|
||||
//set bits of register controlled by mask
|
||||
#define SET_PERI_REG_MASK(reg, mask) WRITE_PERI_REG((reg), (READ_PERI_REG(reg)|(mask)))
|
||||
|
||||
//get bits of register controlled by mask
|
||||
#define GET_PERI_REG_MASK(reg, mask) (READ_PERI_REG(reg) & (mask))
|
||||
#define GET_PERI_REG_BITS(reg, hipos,lowpos) ((READ_PERI_REG(reg)>>(lowpos))&((1<<((hipos)-(lowpos)+1))-1))
|
||||
|
||||
//get bits of register controlled by highest bit and lowest bit
|
||||
#define GET_PERI_REG_BITS(reg, hipos,lowpos) ((READ_PERI_REG(reg)>>(lowpos))&((1<<((hipos)-(lowpos)+1))-1))
|
||||
|
||||
//set bits of register controlled by mask and shift
|
||||
#define SET_PERI_REG_BITS(reg,bit_map,value,shift) (WRITE_PERI_REG((reg),(READ_PERI_REG(reg)&(~((bit_map)<<(shift))))|(((value) & bit_map)<<(shift)) ))
|
||||
|
||||
//get field of register
|
||||
#define GET_PERI_REG_BITS2(reg, mask,shift) ((READ_PERI_REG(reg)>>(shift))&(mask))
|
||||
//}}
|
||||
|
||||
//Periheral Clock {{
|
||||
#define APB_CLK_FREQ_ROM 13*1000000
|
||||
#define APB_CLK_FREQ_ROM 26*1000000
|
||||
#define CPU_CLK_FREQ_ROM APB_CLK_FREQ_ROM
|
||||
#define CPU_CLK_FREQ APB_CLK_FREQ
|
||||
#define APB_CLK_FREQ 80*1000000 //unit: Hz
|
||||
#define UART_CLK_FREQ APB_CLK_FREQ
|
||||
//#define WDT_CLK_FREQ APB_CLK_FREQ
|
||||
#define WDT_CLK_FREQ APB_CLK_FREQ
|
||||
#define TIMER_CLK_FREQ (80000000>>4) //80MHz divided by 16
|
||||
#define SPI_CLK_DIV 4
|
||||
//#define RTC_CLK_FREQ 32768 //unit:Hz
|
||||
//#define RTC_CLK_FREQ 100000 //unit:Hz
|
||||
//#define CALIB_CLK_MHZ 40
|
||||
#define TICKS_PER_US 13 // CPU is 80MHz
|
||||
#define TICKS_PER_US_ROM 26 // CPU is 80MHz
|
||||
//}}
|
||||
|
||||
#if 0
|
||||
//Peripheral device base address define{{
|
||||
#define DR_REG_DPORT_BASE 0x3ff00000
|
||||
#define DR_REG_UART_BASE 0x60000000
|
||||
#define DR_REG_SPI1_BASE 0x60002000 //no
|
||||
#define DR_REG_SPI0_BASE 0x60003000 //no
|
||||
#define DR_REG_GPIO_BASE 0x60004000 //no
|
||||
#define DR_REG_FE2_BASE 0x60005000
|
||||
#define DR_REG_FE_BASE 0x60006000
|
||||
#define DR_REG_TIMER_BASE 0x60007000 //no
|
||||
#define DR_REG_RTCCNTL_BASE 0x60008000
|
||||
#define DR_REG_RTCIO_BASE 0x60008400
|
||||
|
||||
#define DR_REG_RTCMEM0_BASE 0x60021000
|
||||
#define DR_REG_RTCMEM1_BASE 0x60022000
|
||||
#define DR_REG_RTCMEM2_BASE 0x60023000
|
||||
|
||||
#define DR_REG_IO_MUX_BASE 0x60009000 //no
|
||||
#define DR_REG_WDG_BASE 0x6000A000 //no
|
||||
#define DR_REG_HINF_BASE 0x6000B000 //no
|
||||
#define DR_REG_UHCI1_BASE 0x6000C000
|
||||
//#define DR_REG_MISC_BASE 0x6000D000 //no use
|
||||
#define DR_REG_I2C_BASE 0x6000E000 //no
|
||||
#define DR_REG_I2S_BASE 0x6000F000
|
||||
#define DR_REG_UART1_BASE 0x60010000
|
||||
#define DR_REG_BT_BASE 0x60011000
|
||||
//#define DR_REG_BT_BUFFER_BASE 0x60012000 //no use
|
||||
#define DR_REG_I2C_EXT_BASE 0x60013000 //no
|
||||
#define DR_REG_UHCI0_BASE 0x60014000
|
||||
#define DR_REG_SLCHOST_BASE 0x60015000
|
||||
#define DR_REG_RMT_BASE 0x60016000
|
||||
#define DR_REG_PCNT_BASE 0x60017000
|
||||
#define DR_REG_SLC_BASE 0x60018000
|
||||
#define DR_REG_LEDC_BASE 0x60019000
|
||||
#define DR_REG_EFUSE_BASE 0x6001A000
|
||||
#define DR_REG_SPI_ENCRYPT_BASE 0x6001B000
|
||||
#define DR_REG_PWM_BASE 0x6001C000 //no
|
||||
#define DR_REG_TIMERGROUP_BASE 0x6001D000 //no
|
||||
#define DR_REG_TIMERGROUP1_BASE 0x6001E000 //no
|
||||
#define DR_REG_BB_BASE 0x6001F000
|
||||
#define DR_REG_GPIO_SD_BASE 0x60004f00
|
||||
#else
|
||||
#define DR_REG_DPORT_BASE 0x3ff00000
|
||||
#define DR_REG_UART_BASE 0x3ff40000
|
||||
#define DR_REG_SPI1_BASE 0x3ff42000 //no
|
||||
#define DR_REG_SPI0_BASE 0x3ff43000 //no
|
||||
#define DR_REG_GPIO_BASE 0x3ff44000 //no
|
||||
#define DR_REG_SPI1_BASE 0x3ff42000
|
||||
#define DR_REG_SPI0_BASE 0x3ff43000
|
||||
#define DR_REG_GPIO_BASE 0x3ff44000
|
||||
#define DR_REG_FE2_BASE 0x3ff45000
|
||||
#define DR_REG_FE_BASE 0x3ff46000
|
||||
#define DR_REG_TIMER_BASE 0x3ff47000 //no
|
||||
#define DR_REG_TIMER_BASE 0x3ff47000
|
||||
#define DR_REG_RTCCNTL_BASE 0x3ff48000
|
||||
#define DR_REG_RTCIO_BASE 0x3ff48400
|
||||
|
||||
@ -157,18 +152,16 @@
|
||||
#define DR_REG_RTCMEM1_BASE 0x3ff62000
|
||||
#define DR_REG_RTCMEM2_BASE 0x3ff63000
|
||||
|
||||
#define DR_REG_IO_MUX_BASE 0x3ff49000 //no
|
||||
#define DR_REG_WDG_BASE 0x3ff4A000 //no
|
||||
#define DR_REG_HINF_BASE 0x3ff4B000 //no
|
||||
#define DR_REG_IO_MUX_BASE 0x3ff49000
|
||||
#define DR_REG_WDG_BASE 0x3ff4A000
|
||||
#define DR_REG_HINF_BASE 0x3ff4B000
|
||||
#define DR_REG_UHCI1_BASE 0x3ff4C000
|
||||
//#define DR_REG_MISC_BASE 0x6000D000 //no use
|
||||
#define DR_REG_I2C_BASE 0x3ff4E000 //no
|
||||
#define DR_REG_I2C_BASE 0x3ff4E000
|
||||
#define DR_REG_I2S_BASE 0x3ff4F000
|
||||
#define DR_REG_I2S1_BASE 0x3ff6D000
|
||||
#define DR_REG_UART1_BASE 0x3ff50000
|
||||
#define DR_REG_BT_BASE 0x3ff51000
|
||||
//#define DR_REG_BT_BUFFER_BASE 0x60012000 //no use
|
||||
#define DR_REG_I2C_EXT_BASE 0x3ff53000 //no
|
||||
#define DR_REG_I2C_EXT_BASE 0x3ff53000
|
||||
#define DR_REG_UHCI0_BASE 0x3ff54000
|
||||
#define DR_REG_SLCHOST_BASE 0x3ff55000
|
||||
#define DR_REG_RMT_BASE 0x3ff56000
|
||||
@ -177,94 +170,139 @@
|
||||
#define DR_REG_LEDC_BASE 0x3ff59000
|
||||
#define DR_REG_EFUSE_BASE 0x3ff5A000
|
||||
#define DR_REG_SPI_ENCRYPT_BASE 0x3ff5B000
|
||||
#define DR_REG_PWM_BASE 0x3ff5C000 //no
|
||||
#define DR_REG_TIMERS_BASE 0x3ff5F000 //no
|
||||
#define DR_REG_TIMERGROUP1_BASE 0x3ff5E000 //no
|
||||
#define DR_REG_BB_BASE 0x3ff5F000
|
||||
#define DR_REG_BB_BASE 0x3ff5C000
|
||||
#define DR_REG_PWM_BASE 0x3ff5E000
|
||||
#define DR_REG_TIMERS_BASE(i) (0x3ff5F000 + i * (0x1000))
|
||||
#define DR_REG_GPIO_SD_BASE 0x3ff44f00
|
||||
#endif
|
||||
|
||||
//}}
|
||||
#define REG_SPI_BASE(i) (DR_REG_SPI0_BASE - i*(0x1000))
|
||||
#define PERIPHS_TIMER_BASEDDR DR_REG_TIMER_BASE
|
||||
#define PERIPHS_SPI_ENCRYPT_BASEADDR DR_REG_SPI_ENCRYPT_BASE
|
||||
|
||||
#define UART0_UNHOLD_MASK 0x3
|
||||
#define UART1_UNHOLD_MASK 0x60
|
||||
#define SDIO_UNHOLD_MASK 0xfc
|
||||
#define SPI_UNHOLD_MASK 0xfc
|
||||
//Interrupt hardware source table
|
||||
//This table is decided by hardware, don't touch this.
|
||||
#define ETS_WIFI_MAC_INTR_SOURCE 0/**< interrupt of WiFi MAC, level*/
|
||||
#define ETS_WIFI_MAC_NMI_SOURCE 1/**< interrupt of WiFi MAC, NMI, use if MAC have bug to fix in NMI*/
|
||||
#define ETS_WIFI_BB_INTR_SOURCE 2/**< interrupt of WiFi BB, level, we can do some calibartion*/
|
||||
#define ETS_BT_MAC_INTR_SOURCE 3/**< will be cancelled*/
|
||||
#define ETS_BT_BB_INTR_SOURCE 4/**< interrupt of BT BB, level*/
|
||||
#define ETS_BT_BB_NMI_SOURCE 5/**< interrupt of BT BB, NMI, use if BB have bug to fix in NMI*/
|
||||
#define ETS_RWBT_INTR_SOURCE 6/**< interrupt of RWBT, level*/
|
||||
#define ETS_RWBLE_INTR_SOURCE 7/**< interrupt of RWBLE, level*/
|
||||
#define ETS_RWBT_NMI_SOURCE 8/**< interrupt of RWBT, NMI, use if RWBT have bug to fix in NMI*/
|
||||
#define ETS_RWBLE_NMI_SOURCE 9/**< interrupt of RWBLE, NMI, use if RWBT have bug to fix in NMI*/
|
||||
#define ETS_SLC0_INTR_SOURCE 10/**< interrupt of SLC0, level*/
|
||||
#define ETS_SLC1_INTR_SOURCE 11/**< interrupt of SLC1, level*/
|
||||
#define ETS_UHCI0_INTR_SOURCE 12/**< interrupt of UHCI0, level*/
|
||||
#define ETS_UHCI1_INTR_SOURCE 13/**< interrupt of UHCI1, level*/
|
||||
#define ETS_TG0_T0_LEVEL_INTR_SOURCE 14/**< interrupt of TIMER_GROUP0, TIMER0, level, we would like use EDGE for timer if permission*/
|
||||
#define ETS_TG0_T1_LEVEL_INTR_SOURCE 15/**< interrupt of TIMER_GROUP0, TIMER1, level, we would like use EDGE for timer if permission*/
|
||||
#define ETS_TG0_WDT_LEVEL_INTR_SOURCE 16/**< interrupt of TIMER_GROUP0, WATCHDOG, level*/
|
||||
#define ETS_TG0_LACT_LEVEL_INTR_SOURCE 17/**< interrupt of TIMER_GROUP0, LACT, level*/
|
||||
#define ETS_TG1_T0_LEVEL_INTR_SOURCE 18/**< interrupt of TIMER_GROUP1, TIMER0, level, we would like use EDGE for timer if permission*/
|
||||
#define ETS_TG1_T1_LEVEL_INTR_SOURCE 19/**< interrupt of TIMER_GROUP1, TIMER1, level, we would like use EDGE for timer if permission*/
|
||||
#define ETS_TG1_WDT_LEVEL_INTR_SOURCE 20/**< interrupt of TIMER_GROUP1, WATCHDOG, level*/
|
||||
#define ETS_TG1_LACT_LEVEL_INTR_SOURCE 21/**< interrupt of TIMER_GROUP1, LACT, level*/
|
||||
#define ETS_GPIO_INTR_SOURCE 22/**< interrupt of GPIO, level*/
|
||||
#define ETS_GPIO_NMI_SOURCE 23/**< interrupt of GPIO, NMI*/
|
||||
#define ETS_FROM_CPU_INTR0_SOURCE 24/**< interrupt0 generated from a CPU, level*/
|
||||
#define ETS_FROM_CPU_INTR1_SOURCE 25/**< interrupt1 generated from a CPU, level*/
|
||||
#define ETS_FROM_CPU_INTR2_SOURCE 26/**< interrupt2 generated from a CPU, level*/
|
||||
#define ETS_FROM_CPU_INTR3_SOURCE 27/**< interrupt3 generated from a CPU, level*/
|
||||
#define ETS_SPI0_INTR_SOURCE 28/**< interrupt of SPI0, level, SPI0 is for Cache Access, do not use this*/
|
||||
#define ETS_SPI1_INTR_SOURCE 29/**< interrupt of SPI1, level, SPI1 is for flash read/write, do not use this*/
|
||||
#define ETS_SPI2_INTR_SOURCE 30/**< interrupt of SPI2, level*/
|
||||
#define ETS_SPI3_INTR_SOURCE 31/**< interrupt of SPI3, level*/
|
||||
#define ETS_I2S0_INTR_SOURCE 32/**< interrupt of I2S0, level*/
|
||||
#define ETS_I2S1_INTR_SOURCE 33/**< interrupt of I2S1, level*/
|
||||
#define ETS_UART0_INTR_SOURCE 34/**< interrupt of UART0, level*/
|
||||
#define ETS_UART1_INTR_SOURCE 35/**< interrupt of UART1, level*/
|
||||
#define ETS_UART2_INTR_SOURCE 36/**< interrupt of UART2, level*/
|
||||
#define ETS_SDIO_HOST_INTR_SOURCE 37/**< interrupt of SD/SDIO/MMC HOST, level*/
|
||||
#define ETS_ETH_MAC_INTR_SOURCE 38/**< interrupt of ethernet mac, level*/
|
||||
#define ETS_PWM0_INTR_SOURCE 39/**< interrupt of PWM0, level, Reserved*/
|
||||
#define ETS_PWM1_INTR_SOURCE 40/**< interrupt of PWM1, level, Reserved*/
|
||||
#define ETS_PWM2_INTR_SOURCE 41/**< interrupt of PWM2, level*/
|
||||
#define ETS_PWM3_INTR_SOURCE 42/**< interruot of PWM3, level*/
|
||||
#define ETS_LEDC_INTR_SOURCE 43/**< interrupt of LED PWM, level*/
|
||||
#define ETS_EFUSE_INTR_SOURCE 44/**< interrupt of efuse, level, not likely to use*/
|
||||
#define ETS_CAN_INTR_SOURCE 45/**< interrupt of can, level*/
|
||||
#define ETS_RTC_CORE_INTR_SOURCE 46/**< interrupt of rtc core, level, include rtc watchdog*/
|
||||
#define ETS_RMT_INTR_SOURCE 47/**< interrupt of remote controller, level*/
|
||||
#define ETS_PCNT_INTR_SOURCE 48/**< interrupt of pluse count, level*/
|
||||
#define ETS_I2C_EXT0_INTR_SOURCE 49/**< interrupt of I2C controller1, level*/
|
||||
#define ETS_I2C_EXT1_INTR_SOURCE 50/**< interrupt of I2C controller0, level*/
|
||||
#define ETS_RSA_INTR_SOURCE 51/**< interrupt of RSA accelerator, level*/
|
||||
#define ETS_SPI1_DMA_INTR_SOURCE 52/**< interrupt of SPI1 DMA, SPI1 is for flash read/write, do not use this*/
|
||||
#define ETS_SPI2_DMA_INTR_SOURCE 53/**< interrupt of SPI2 DMA, level*/
|
||||
#define ETS_SPI3_DMA_INTR_SOURCE 54/**< interrupt of SPI3 DMA, level*/
|
||||
#define ETS_WDT_INTR_SOURCE 55/**< will be cancelled*/
|
||||
#define ETS_TIMER1_INTR_SOURCE 56/**< will be cancelled*/
|
||||
#define ETS_TIMER2_INTR_SOURCE 57/**< will be cancelled*/
|
||||
#define ETS_TG0_T0_EDGE_INTR_SOURCE 58/**< interrupt of TIMER_GROUP0, TIMER0, EDGE*/
|
||||
#define ETS_TG0_T1_EDGE_INTR_SOURCE 59/**< interrupt of TIMER_GROUP0, TIMER1, EDGE*/
|
||||
#define ETS_TG0_WDT_EDGE_INTR_SOURCE 60/**< interrupt of TIMER_GROUP0, WATCH DOG, EDGE*/
|
||||
#define ETS_TG0_LACT_EDGE_INTR_SOURCE 61/**< interrupt of TIMER_GROUP0, LACT, EDGE*/
|
||||
#define ETS_TG1_T0_EDGE_INTR_SOURCE 62/**< interrupt of TIMER_GROUP1, TIMER0, EDGE*/
|
||||
#define ETS_TG1_T1_EDGE_INTR_SOURCE 63/**< interrupt of TIMER_GROUP1, TIMER1, EDGE*/
|
||||
#define ETS_TG1_WDT_EDGE_INTR_SOURCE 64/**< interrupt of TIMER_GROUP1, WATCHDOG, EDGE*/
|
||||
#define ETS_TG1_LACT_EDGE_INTR_SOURCE 65/**< interrupt of TIMER_GROUP0, LACT, EDGE*/
|
||||
#define ETS_MMU_IA_INTR_SOURCE 66/**< interrupt of MMU Invalid Access, LEVEL*/
|
||||
#define ETS_MPU_IA_INTR_SOURCE 67/**< interrupt of MPU Invalid Access, LEVEL*/
|
||||
#define ETS_CACHE_IA_INTR_SOURCE 68/**< interrupt of Cache Invalied Access, LEVEL*/
|
||||
|
||||
// TIMER reg {{
|
||||
#define TIMER_REG_READ(addr) READ_PERI_REG(addr)
|
||||
#define TIMER_REG_WRITE(addr, val) WRITE_PERI_REG(addr, val)
|
||||
#define TIMER_SET_REG_MASK(reg, mask) WRITE_PERI_REG(reg, (READ_PERI_REG(reg)|(mask)))
|
||||
/* Returns the current time according to the timer timer. */
|
||||
#define NOW() TIMER_REG_READ(FRC2_COUNT_ADDRESS)
|
||||
//load initial_value to timer1
|
||||
#define FRC1_LOAD_ADDRESS (PERIPHS_TIMER_BASEDDR +0x00)
|
||||
#define FRC1_LOAD_DATA_MSB 22
|
||||
#define FRC1_LOAD_DATA_LSB 0
|
||||
#define FRC1_LOAD_DATA_MASK 0x007fffff
|
||||
//interrupt cpu using table, Please see the core-isa.h
|
||||
/*************************************************************************************************************
|
||||
* Intr num Level Type PRO CPU usage APP CPU uasge
|
||||
* 0 1 extern level WMAC Reserved
|
||||
* 1 1 extern level BT/BLE Host Reserved
|
||||
* 2 1 extern level FROM_CPU FROM_CPU
|
||||
* 3 1 extern level TG0_WDT Reserved
|
||||
* 4 1 extern level WBB
|
||||
* 5 1 extern level Reserved
|
||||
* 6 1 timer FreeRTOS Tick(L1) FreeRTOS Tick(L1)
|
||||
* 7 1 software Reserved Reserved
|
||||
* 8 1 extern level Reserved
|
||||
* 9 1 extern level
|
||||
* 10 1 extern edge Internal Timer
|
||||
* 11 3 profiling
|
||||
* 12 1 extern level
|
||||
* 13 1 extern level
|
||||
* 14 7 nmi Reserved Reserved
|
||||
* 15 3 timer FreeRTOS Tick(L3) FreeRTOS Tick(L3)
|
||||
* 16 5 timer
|
||||
* 17 1 extern level
|
||||
* 18 1 extern level
|
||||
* 19 2 extern level
|
||||
* 20 2 extern level
|
||||
* 21 2 extern level
|
||||
* 22 3 extern edge
|
||||
* 23 3 extern level
|
||||
* 24 4 extern level
|
||||
* 25 4 extern level Reserved Reserved
|
||||
* 26 5 extern level Reserved Reserved
|
||||
* 27 3 extern level Reserved Reserved
|
||||
* 28 4 extern edge
|
||||
* 29 3 software Reserved Reserved
|
||||
* 30 4 extern edge Reserved Reserved
|
||||
* 31 5 extern level Reserved Reserved
|
||||
*************************************************************************************************************
|
||||
*/
|
||||
|
||||
//timer1's counter value(count from initial_value to 0)
|
||||
#define FRC1_COUNT_ADDRESS (PERIPHS_TIMER_BASEDDR +0x04)
|
||||
#define FRC1_COUNT_DATA_MSB 22
|
||||
#define FRC1_COUNT_DATA_LSB 0
|
||||
#define FRC1_COUNT_DATA_MASK 0x007fffff
|
||||
//CPU0 Interrupt number reserved, not touch this.
|
||||
#define ETS_WMAC_INUM 0
|
||||
#define ETS_BT_HOST_INUM 1
|
||||
#define ETS_FROM_CPU_INUM 2
|
||||
#define ETS_T0_WDT_INUM 3
|
||||
#define ETS_WBB_INUM 4
|
||||
#define ETS_TG0_T1_INUM 10 /**< use edge interrupt*/
|
||||
|
||||
#define FRC1_CTRL_ADDRESS (PERIPHS_TIMER_BASEDDR +0x08)
|
||||
#define FRC1_CTRL_DATA_MSB 7
|
||||
#define FRC1_CTRL_DATA_LSB 0
|
||||
#define FRC1_CTRL_DATA_MASK 0x000000ff
|
||||
//CPU0 Intrrupt number used in ROM, should be cancelled in SDK
|
||||
#define ETS_SLC_INUM 1
|
||||
#define ETS_UART0_INUM 5
|
||||
#define ETS_UART1_INUM 5
|
||||
|
||||
//clear timer1's interrupt when write this address
|
||||
#define FRC1_INT_ADDRESS (PERIPHS_TIMER_BASEDDR +0x0c)
|
||||
#define FRC1_INT_CLR_MSB 0
|
||||
#define FRC1_INT_CLR_LSB 0
|
||||
#define FRC1_INT_CLR_MASK 0x00000001
|
||||
|
||||
//only used for simulation
|
||||
#define FRC1_TEST_ADDRESS (PERIPHS_TIMER_BASEDDR +0x10)
|
||||
#define FRC1_TEST_MODE_MSB 0
|
||||
#define FRC1_TEST_MODE_LSB 0
|
||||
#define FRC1_TEST_MODE_MASK 0x00000001
|
||||
|
||||
//load initial_value to timer2
|
||||
#define FRC2_LOAD_ADDRESS (PERIPHS_TIMER_BASEDDR +0x20)
|
||||
#define FRC2_LOAD_DATA_MSB 31
|
||||
#define FRC2_LOAD_DATA_LSB 0
|
||||
#define FRC2_LOAD_DATA_MASK 0xffffffff
|
||||
|
||||
//timer2's counter value(count from initial_value to 0)
|
||||
#define FRC2_COUNT_ADDRESS (PERIPHS_TIMER_BASEDDR +0x24)
|
||||
#define FRC2_COUNT_DATA_MSB 31
|
||||
#define FRC2_COUNT_DATA_LSB 0
|
||||
#define FRC2_COUNT_DATA_MASK 0xffffffff
|
||||
|
||||
#define FRC2_CTRL_ADDRESS (PERIPHS_TIMER_BASEDDR +0x28)
|
||||
#define FRC2_CTRL_DATA_MSB 7
|
||||
#define FRC2_CTRL_DATA_LSB 0
|
||||
#define FRC2_CTRL_DATA_MASK 0x000000ff
|
||||
|
||||
//clear interrupt when write this address
|
||||
#define FRC2_INT_ADDRESS (PERIPHS_TIMER_BASEDDR +0x2c)
|
||||
#define FRC2_INT_CLR_MSB 0
|
||||
#define FRC2_INT_CLR_LSB 0
|
||||
#define FRC2_INT_CLR_MASK 0x00000001
|
||||
|
||||
//set Alarm_value for timer2 to generate interrupt
|
||||
#define FRC2_ALARM_ADDRESS (PERIPHS_TIMER_BASEDDR +0x30)
|
||||
#define FRC2_ALARM_DATA_MSB 31
|
||||
#define FRC2_ALARM_DATA_LSB 0
|
||||
#define FRC2_ALARM_DATA_MASK 0xffffffff
|
||||
// }}
|
||||
|
||||
#define SPI_ENCRYPT_CNTL (PERIPHS_SPI_ENCRYPT_BASEADDR + 0x20)
|
||||
#define SPI_ENCRYPT_CNTL_ENA BIT(0)
|
||||
|
||||
#define SPI_ENCRYPT_ADDR (PERIPHS_SPI_ENCRYPT_BASEADDR + 0x24)
|
||||
|
||||
#define SPI_ENCRYPT_CHECKDONE (PERIPHS_SPI_ENCRYPT_BASEADDR + 0x28)
|
||||
#define SPI_ENCRYPT_CHECKDONE_STATUS BIT(0)
|
||||
|
||||
#endif /* _ESP32_SOC_H_ */
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
#include "soc.h"
|
||||
|
||||
#define T0CONFIG (DR_REG_TIMERS_BASE + 0x0000)
|
||||
#define T0CONFIG(i) (DR_REG_TIMERS_BASE(i) + 0x0000)
|
||||
#define TIMERS_T0_EN (BIT(31))
|
||||
#define TIMERS_T0_EN_S 31
|
||||
#define TIMERS_T0_INCREASE (BIT(30))
|
||||
@ -32,39 +32,39 @@
|
||||
#define TIMERS_T0_ALARM_EN (BIT(10))
|
||||
#define TIMERS_T0_ALARM_EN_S 10
|
||||
|
||||
#define T0LO (DR_REG_TIMERS_BASE + 0x0004)
|
||||
#define T0LO(i) (DR_REG_TIMERS_BASE(i) + 0x0004)
|
||||
#define TIMERS_T0_LO 0xFFFFFFFF
|
||||
#define TIMERS_T0_LO_S 0
|
||||
|
||||
#define T0HI (DR_REG_TIMERS_BASE + 0x0008)
|
||||
#define T0HI(i) (DR_REG_TIMERS_BASE(i) + 0x0008)
|
||||
#define TIMERS_T0_HI 0xFFFFFFFF
|
||||
#define TIMERS_T0_HI_S 0
|
||||
|
||||
#define T0UPDATE (DR_REG_TIMERS_BASE + 0x000c)
|
||||
#define T0UPDATE(i) (DR_REG_TIMERS_BASE(i) + 0x000c)
|
||||
#define TIMERS_T0_UPDATE 0xFFFFFFFF
|
||||
#define TIMERS_T0_UPDATE_S 0
|
||||
|
||||
#define T0ALARMLO (DR_REG_TIMERS_BASE + 0x0010)
|
||||
#define T0ALARMLO(i) (DR_REG_TIMERS_BASE(i) + 0x0010)
|
||||
#define TIMERS_T0_ALARM_LO 0xFFFFFFFF
|
||||
#define TIMERS_T0_ALARM_LO_S 0
|
||||
|
||||
#define T0ALARMHI (DR_REG_TIMERS_BASE + 0x0014)
|
||||
#define T0ALARMHI(i) (DR_REG_TIMERS_BASE(i) + 0x0014)
|
||||
#define TIMERS_T0_ALARM_HI 0xFFFFFFFF
|
||||
#define TIMERS_T0_ALARM_HI_S 0
|
||||
|
||||
#define T0LOADLO (DR_REG_TIMERS_BASE + 0x0018)
|
||||
#define T0LOADLO(i) (DR_REG_TIMERS_BASE(i) + 0x0018)
|
||||
#define TIMERS_T0_LOAD_LO 0xFFFFFFFF
|
||||
#define TIMERS_T0_LOAD_LO_S 0
|
||||
|
||||
#define T0LOADHI (DR_REG_TIMERS_BASE + 0x001c)
|
||||
#define T0LOADHI(i) (DR_REG_TIMERS_BASE(i) + 0x001c)
|
||||
#define TIMERS_T0_LOAD_HI 0xFFFFFFFF
|
||||
#define TIMERS_T0_LOAD_HI_S 0
|
||||
|
||||
#define T0LOAD (DR_REG_TIMERS_BASE + 0x0020)
|
||||
#define T0LOAD(i) (DR_REG_TIMERS_BASE(i) + 0x0020)
|
||||
#define TIMERS_T0_LOAD 0xFFFFFFFF
|
||||
#define TIMERS_T0_LOAD_S 0
|
||||
|
||||
#define T1CONFIG (DR_REG_TIMERS_BASE + 0x0024)
|
||||
#define T1CONFIG(i) (DR_REG_TIMERS_BASE(i) + 0x0024)
|
||||
#define TIMERS_T1_EN (BIT(31))
|
||||
#define TIMERS_T1_EN_S 31
|
||||
#define TIMERS_T1_INCREASE (BIT(30))
|
||||
@ -80,39 +80,39 @@
|
||||
#define TIMERS_T1_ALARM_EN (BIT(10))
|
||||
#define TIMERS_T1_ALARM_EN_S 10
|
||||
|
||||
#define T1LO (DR_REG_TIMERS_BASE + 0x0028)
|
||||
#define T1LO(i) (DR_REG_TIMERS_BASE(i) + 0x0028)
|
||||
#define TIMERS_T1_LO 0xFFFFFFFF
|
||||
#define TIMERS_T1_LO_S 0
|
||||
|
||||
#define T1HI (DR_REG_TIMERS_BASE + 0x002c)
|
||||
#define T1HI(i) (DR_REG_TIMERS_BASE(i) + 0x002c)
|
||||
#define TIMERS_T1_HI 0xFFFFFFFF
|
||||
#define TIMERS_T1_HI_S 0
|
||||
|
||||
#define T1UPDATE (DR_REG_TIMERS_BASE + 0x0030)
|
||||
#define T1UPDATE(i) (DR_REG_TIMERS_BASE(i) + 0x0030)
|
||||
#define TIMERS_T1_UPDATE 0xFFFFFFFF
|
||||
#define TIMERS_T1_UPDATE_S 0
|
||||
|
||||
#define T1ALARMLO (DR_REG_TIMERS_BASE + 0x0034)
|
||||
#define T1ALARMLO(i) (DR_REG_TIMERS_BASE(i) + 0x0034)
|
||||
#define TIMERS_T1_ALARM_LO 0xFFFFFFFF
|
||||
#define TIMERS_T1_ALARM_LO_S 0
|
||||
|
||||
#define T1ALARMHI (DR_REG_TIMERS_BASE + 0x0038)
|
||||
#define T1ALARMHI(i) (DR_REG_TIMERS_BASE(i) + 0x0038)
|
||||
#define TIMERS_T1_ALARM_HI 0xFFFFFFFF
|
||||
#define TIMERS_T1_ALARM_HI_S 0
|
||||
|
||||
#define T1LOADLO (DR_REG_TIMERS_BASE + 0x003c)
|
||||
#define T1LOADLO(i) (DR_REG_TIMERS_BASE(i) + 0x003c)
|
||||
#define TIMERS_T1_LOAD_LO 0xFFFFFFFF
|
||||
#define TIMERS_T1_LOAD_LO_S 0
|
||||
|
||||
#define T1LOADHI (DR_REG_TIMERS_BASE + 0x0040)
|
||||
#define T1LOADHI(i) (DR_REG_TIMERS_BASE(i) + 0x0040)
|
||||
#define TIMERS_T1_LOAD_HI 0xFFFFFFFF
|
||||
#define TIMERS_T1_LOAD_HI_S 0
|
||||
|
||||
#define T1LOAD (DR_REG_TIMERS_BASE + 0x0044)
|
||||
#define T1LOAD(i) (DR_REG_TIMERS_BASE(i) + 0x0044)
|
||||
#define TIMERS_T1_LOAD 0xFFFFFFFF
|
||||
#define TIMERS_T1_LOAD_S 0
|
||||
|
||||
#define WDTCONFIG0 (DR_REG_TIMERS_BASE + 0x0048)
|
||||
#define WDTCONFIG0(i) (DR_REG_TIMERS_BASE(i) + 0x0048)
|
||||
#define TIMERS_WDT_EN (BIT(31))
|
||||
#define TIMERS_WDT_EN_S 31
|
||||
#define TIMERS_WDT_STG0 0x00000003
|
||||
@ -134,35 +134,35 @@
|
||||
#define TIMERS_WDT_FLASHBOOT_MOD_EN (BIT(14))
|
||||
#define TIMERS_WDT_FLASHBOOT_MOD_EN_S 14
|
||||
|
||||
#define WDTCONFIG1 (DR_REG_TIMERS_BASE + 0x004c)
|
||||
#define WDTCONFIG1(i) (DR_REG_TIMERS_BASE(i) + 0x004c)
|
||||
#define TIMERS_WDT_CLK_PRESCALE 0x0000FFFF
|
||||
#define TIMERS_WDT_CLK_PRESCALE_S 16
|
||||
|
||||
#define WDTCONFIG2 (DR_REG_TIMERS_BASE + 0x0050)
|
||||
#define WDTCONFIG2(i) (DR_REG_TIMERS_BASE(i) + 0x0050)
|
||||
#define TIMERS_WDT_STG0_HOLD 0xFFFFFFFF
|
||||
#define TIMERS_WDT_STG0_HOLD_S 0
|
||||
|
||||
#define WDTCONFIG3 (DR_REG_TIMERS_BASE + 0x0054)
|
||||
#define WDTCONFIG3(i) (DR_REG_TIMERS_BASE(i) + 0x0054)
|
||||
#define TIMERS_WDT_STG1_HOLD 0xFFFFFFFF
|
||||
#define TIMERS_WDT_STG1_HOLD_S 0
|
||||
|
||||
#define WDTCONFIG4 (DR_REG_TIMERS_BASE + 0x0058)
|
||||
#define WDTCONFIG4(i) (DR_REG_TIMERS_BASE(i) + 0x0058)
|
||||
#define TIMERS_WDT_STG2_HOLD 0xFFFFFFFF
|
||||
#define TIMERS_WDT_STG2_HOLD_S 0
|
||||
|
||||
#define WDTCONFIG5 (DR_REG_TIMERS_BASE + 0x005c)
|
||||
#define WDTCONFIG5(i) (DR_REG_TIMERS_BASE(i) + 0x005c)
|
||||
#define TIMERS_WDT_STG3_HOLD 0xFFFFFFFF
|
||||
#define TIMERS_WDT_STG3_HOLD_S 0
|
||||
|
||||
#define WDTFEED (DR_REG_TIMERS_BASE + 0x0060)
|
||||
#define WDTFEED(i) (DR_REG_TIMERS_BASE(i) + 0x0060)
|
||||
#define TIMERS_WDT_FEED 0xFFFFFFFF
|
||||
#define TIMERS_WDT_FEED_S 0
|
||||
|
||||
#define WDTWPROTECT (DR_REG_TIMERS_BASE + 0x0064)
|
||||
#define WDTWPROTECT(i) (DR_REG_TIMERS_BASE(i) + 0x0064)
|
||||
#define TIMERS_WDT_WKEY 0xFFFFFFFF
|
||||
#define TIMERS_WDT_WKEY_S 0
|
||||
|
||||
#define RTCCALICFG (DR_REG_TIMERS_BASE + 0x0068)
|
||||
#define RTCCALICFG(i) (DR_REG_TIMERS_BASE(i) + 0x0068)
|
||||
#define TIMERS_RTC_CALI_START (BIT(31))
|
||||
#define TIMERS_RTC_CALI_START_S 31
|
||||
#define TIMERS_RTC_CALI_MAX 0x00007FFF
|
||||
@ -174,11 +174,11 @@
|
||||
#define TIMERS_RTC_CALI_START_CYCLING (BIT(12))
|
||||
#define TIMERS_RTC_CALI_START_CYCLING_S 12
|
||||
|
||||
#define RTCCALICFG1 (DR_REG_TIMERS_BASE + 0x006c)
|
||||
#define RTCCALICFG1(i) (DR_REG_TIMERS_BASE(i) + 0x006c)
|
||||
#define TIMERS_RTC_CALI_VALUE 0x01FFFFFF
|
||||
#define TIMERS_RTC_CALI_VALUE_S 7
|
||||
|
||||
#define LACTCONFIG (DR_REG_TIMERS_BASE + 0x0070)
|
||||
#define LACTCONFIG(i) (DR_REG_TIMERS_BASE(i) + 0x0070)
|
||||
#define TIMERS_LACT_EN (BIT(31))
|
||||
#define TIMERS_LACT_EN_S 31
|
||||
#define TIMERS_LACT_INCREASE (BIT(30))
|
||||
@ -200,43 +200,43 @@
|
||||
#define TIMERS_LACT_RTC_ONLY (BIT(7))
|
||||
#define TIMERS_LACT_RTC_ONLY_S 7
|
||||
|
||||
#define LACTRTC (DR_REG_TIMERS_BASE + 0x0074)
|
||||
#define LACTRTC(i) (DR_REG_TIMERS_BASE(i) + 0x0074)
|
||||
#define TIMERS_LACT_RTC_STEP_LEN 0x03FFFFFF
|
||||
#define TIMERS_LACT_RTC_STEP_LEN_S 6
|
||||
|
||||
#define LACTLO (DR_REG_TIMERS_BASE + 0x0078)
|
||||
#define LACTLO(i) (DR_REG_TIMERS_BASE(i) + 0x0078)
|
||||
#define TIMERS_LACT_LO 0xFFFFFFFF
|
||||
#define TIMERS_LACT_LO_S 0
|
||||
|
||||
#define LACTHI (DR_REG_TIMERS_BASE + 0x007c)
|
||||
#define LACTHI(i) (DR_REG_TIMERS_BASE(i) + 0x007c)
|
||||
#define TIMERS_LACT_HI 0xFFFFFFFF
|
||||
#define TIMERS_LACT_HI_S 0
|
||||
|
||||
#define LACTUPDATE (DR_REG_TIMERS_BASE + 0x0080)
|
||||
#define LACTUPDATE(i) (DR_REG_TIMERS_BASE(i) + 0x0080)
|
||||
#define TIMERS_LACT_UPDATE 0xFFFFFFFF
|
||||
#define TIMERS_LACT_UPDATE_S 0
|
||||
|
||||
#define LACTALARMLO (DR_REG_TIMERS_BASE + 0x0084)
|
||||
#define LACTALARMLO(i) (DR_REG_TIMERS_BASE(i) + 0x0084)
|
||||
#define TIMERS_LACT_ALARM_LO 0xFFFFFFFF
|
||||
#define TIMERS_LACT_ALARM_LO_S 0
|
||||
|
||||
#define LACTALARMHI (DR_REG_TIMERS_BASE + 0x0088)
|
||||
#define LACTALARMHI(i) (DR_REG_TIMERS_BASE(i) + 0x0088)
|
||||
#define TIMERS_LACT_ALARM_HI 0xFFFFFFFF
|
||||
#define TIMERS_LACT_ALARM_HI_S 0
|
||||
|
||||
#define LACTLOADLO (DR_REG_TIMERS_BASE + 0x008c)
|
||||
#define LACTLOADLO(i) (DR_REG_TIMERS_BASE(i) + 0x008c)
|
||||
#define TIMERS_LACT_LOAD_LO 0xFFFFFFFF
|
||||
#define TIMERS_LACT_LOAD_LO_S 0
|
||||
|
||||
#define LACTLOADHI (DR_REG_TIMERS_BASE + 0x0090)
|
||||
#define LACTLOADHI(i) (DR_REG_TIMERS_BASE(i) + 0x0090)
|
||||
#define TIMERS_LACT_LOAD_HI 0xFFFFFFFF
|
||||
#define TIMERS_LACT_LOAD_HI_S 0
|
||||
|
||||
#define LACTLOAD (DR_REG_TIMERS_BASE + 0x0094)
|
||||
#define LACTLOAD(i) (DR_REG_TIMERS_BASE(i) + 0x0094)
|
||||
#define TIMERS_LACT_LOAD 0xFFFFFFFF
|
||||
#define TIMERS_LACT_LOAD_S 0
|
||||
|
||||
#define INT_ENA_TIMERS (DR_REG_TIMERS_BASE + 0x0098)
|
||||
#define INT_ENA_TIMERS(i) (DR_REG_TIMERS_BASE(i) + 0x0098)
|
||||
#define TIMERS_LACT_INT_ENA (BIT(3))
|
||||
#define TIMERS_LACT_INT_ENA_S 3
|
||||
#define TIMERS_WDT_INT_ENA (BIT(2))
|
||||
@ -246,7 +246,7 @@
|
||||
#define TIMERS_T0_INT_ENA (BIT(0))
|
||||
#define TIMERS_T0_INT_ENA_S 0
|
||||
|
||||
#define INT_RAW_TIMERS (DR_REG_TIMERS_BASE + 0x009c)
|
||||
#define INT_RAW_TIMERS(i) (DR_REG_TIMERS_BASE(i) + 0x009c)
|
||||
#define TIMERS_LACT_INT_RAW (BIT(3))
|
||||
#define TIMERS_LACT_INT_RAW_S 3
|
||||
#define TIMERS_WDT_INT_RAW (BIT(2))
|
||||
@ -256,7 +256,7 @@
|
||||
#define TIMERS_T0_INT_RAW (BIT(0))
|
||||
#define TIMERS_T0_INT_RAW_S 0
|
||||
|
||||
#define INT_ST_TIMERS (DR_REG_TIMERS_BASE + 0x00a0)
|
||||
#define INT_ST_TIMERS(i) (DR_REG_TIMERS_BASE(i) + 0x00a0)
|
||||
#define TIMERS_LACT_INT_ST (BIT(3))
|
||||
#define TIMERS_LACT_INT_ST_S 3
|
||||
#define TIMERS_WDT_INT_ST (BIT(2))
|
||||
@ -266,7 +266,7 @@
|
||||
#define TIMERS_T0_INT_ST (BIT(0))
|
||||
#define TIMERS_T0_INT_ST_S 0
|
||||
|
||||
#define INT_CLR_TIMERS (DR_REG_TIMERS_BASE + 0x00a4)
|
||||
#define INT_CLR_TIMERS(i) (DR_REG_TIMERS_BASE(i) + 0x00a4)
|
||||
#define TIMERS_LACT_INT_CLR (BIT(3))
|
||||
#define TIMERS_LACT_INT_CLR_S 3
|
||||
#define TIMERS_WDT_INT_CLR (BIT(2))
|
||||
@ -276,12 +276,12 @@
|
||||
#define TIMERS_T0_INT_CLR (BIT(0))
|
||||
#define TIMERS_T0_INT_CLR_S 0
|
||||
|
||||
#define NTIMERS_DATE (DR_REG_TIMERS_BASE + 0x00f8)
|
||||
#define NTIMERS_DATE(i) (DR_REG_TIMERS_BASE(i) + 0x00f8)
|
||||
#define TIMERS_NTIMERS_DATE 0x0FFFFFFF
|
||||
#define TIMERS_NTIMERS_DATE_S 0
|
||||
#define TIMERS_NTIMERS_DATE_VERSION 0x1604290
|
||||
|
||||
#define REGCLK (DR_REG_TIMERS_BASE + 0x00fc)
|
||||
#define REGCLK(i) (DR_REG_TIMERS_BASE(i) + 0x00fc)
|
||||
#define TIMERS_CLK_EN (BIT(31))
|
||||
#define TIMERS_CLK_EN_S 31
|
||||
|
||||
|
117
components/esp32/ipc.c
Normal file
117
components/esp32/ipc.c
Normal file
@ -0,0 +1,117 @@
|
||||
// Copyright 2015-2016 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_ipc.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
|
||||
|
||||
static TaskHandle_t s_ipc_tasks[portNUM_PROCESSORS]; // Two high priority tasks, one for each CPU
|
||||
static SemaphoreHandle_t s_ipc_mutex; // This mutex is used as a global lock for esp_ipc_* APIs
|
||||
static SemaphoreHandle_t s_ipc_sem[portNUM_PROCESSORS]; // Two semaphores used to wake each of s_ipc_tasks
|
||||
static SemaphoreHandle_t s_ipc_ack; // Semaphore used to acknowledge that task was woken up,
|
||||
// or function has finished running
|
||||
static volatile esp_ipc_func_t s_func; // Function which should be called by high priority task
|
||||
static void * volatile s_func_arg; // Argument to pass into s_func
|
||||
typedef enum {
|
||||
IPC_WAIT_FOR_START,
|
||||
IPC_WAIT_FOR_END
|
||||
} esp_ipc_wait_t;
|
||||
|
||||
static volatile esp_ipc_wait_t s_ipc_wait; // This variable tells high priority task when it should give
|
||||
// s_ipc_ack semaphore: before s_func is called, or
|
||||
// after it returns
|
||||
|
||||
static void IRAM_ATTR ipc_task(void* arg)
|
||||
{
|
||||
const uint32_t cpuid = (uint32_t) arg;
|
||||
assert(cpuid == xPortGetCoreID());
|
||||
while (true) {
|
||||
// Wait for IPC to be initiated.
|
||||
// This will be indicated by giving the semaphore corresponding to
|
||||
// this CPU.
|
||||
if (xSemaphoreTake(s_ipc_sem[cpuid], portMAX_DELAY) != pdTRUE) {
|
||||
// TODO: when can this happen?
|
||||
abort();
|
||||
}
|
||||
|
||||
esp_ipc_func_t func = s_func;
|
||||
void* arg = s_func_arg;
|
||||
|
||||
if (s_ipc_wait == IPC_WAIT_FOR_START) {
|
||||
xSemaphoreGive(s_ipc_ack);
|
||||
}
|
||||
(*func)(arg);
|
||||
if (s_ipc_wait == IPC_WAIT_FOR_END) {
|
||||
xSemaphoreGive(s_ipc_ack);
|
||||
}
|
||||
}
|
||||
// TODO: currently this is unreachable code. Introduce esp_ipc_uninit
|
||||
// function which will signal to both tasks that they can shut down.
|
||||
// Not critical at this point, we don't have a use case for stopping
|
||||
// IPC yet.
|
||||
// Also need to delete the semaphore here.
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
void esp_ipc_init()
|
||||
{
|
||||
s_ipc_mutex = xSemaphoreCreateMutex();
|
||||
s_ipc_ack = xSemaphoreCreateBinary();
|
||||
const char* task_names[2] = {"ipc0", "ipc1"};
|
||||
for (int i = 0; i < portNUM_PROCESSORS; ++i) {
|
||||
s_ipc_sem[i] = xSemaphoreCreateBinary();
|
||||
xTaskCreatePinnedToCore(ipc_task, task_names[i], XT_STACK_MIN_SIZE, (void*) i,
|
||||
configMAX_PRIORITIES - 1, &s_ipc_tasks[i], i);
|
||||
}
|
||||
}
|
||||
|
||||
static esp_err_t esp_ipc_call_and_wait(uint32_t cpu_id, esp_ipc_func_t func, void* arg, esp_ipc_wait_t wait_for)
|
||||
{
|
||||
if (cpu_id >= portNUM_PROCESSORS) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if (xTaskGetSchedulerState() != taskSCHEDULER_RUNNING) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
xSemaphoreTake(s_ipc_mutex, portMAX_DELAY);
|
||||
|
||||
s_func = func;
|
||||
s_func_arg = arg;
|
||||
s_ipc_wait = IPC_WAIT_FOR_START;
|
||||
xSemaphoreGive(s_ipc_sem[cpu_id]);
|
||||
xSemaphoreTake(s_ipc_ack, portMAX_DELAY);
|
||||
xSemaphoreGive(s_ipc_mutex);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t esp_ipc_call(uint32_t cpu_id, esp_ipc_func_t func, void* arg)
|
||||
{
|
||||
return esp_ipc_call_and_wait(cpu_id, func, arg, IPC_WAIT_FOR_START);
|
||||
}
|
||||
|
||||
esp_err_t esp_ipc_call_blocking(uint32_t cpu_id, esp_ipc_func_t func, void* arg)
|
||||
{
|
||||
return esp_ipc_call_and_wait(cpu_id, func, arg, IPC_WAIT_FOR_END);
|
||||
}
|
||||
|
@ -64,6 +64,8 @@ PROVIDE ( Cache_Read_Disable = 0x40009ab8 );
|
||||
PROVIDE ( Cache_Read_Enable = 0x40009a84 );
|
||||
PROVIDE ( Cache_Read_Init = 0x40009950 );
|
||||
PROVIDE ( cache_sram_mmu_set = 0x400097f4 );
|
||||
/* This is static function, but can be used, not generated by script*/
|
||||
PROVIDE ( calc_rtc_memory_crc = 0x40008170 );
|
||||
PROVIDE ( calloc = 0x4000bee4 );
|
||||
PROVIDE ( _calloc_r = 0x4000bbf8 );
|
||||
PROVIDE ( check_pos = 0x400068b8 );
|
||||
@ -1585,12 +1587,20 @@ PROVIDE ( SPIParamCfg = 0x40063238 );
|
||||
PROVIDE ( SPI_Prepare_Encrypt_Data = 0x40062e1c );
|
||||
PROVIDE ( SPIRead = 0x40062ed8 );
|
||||
PROVIDE ( SPIReadModeCnfig = 0x40062944 );
|
||||
/* This is static function, but can be used, not generated by script*/
|
||||
PROVIDE ( SPI_read_status = 0x4006226c );
|
||||
/* This is static function, but can be used, not generated by script*/
|
||||
PROVIDE ( SPI_read_status_high = 0x40062448 );
|
||||
PROVIDE ( SPIUnlock = 0x400628b0 );
|
||||
PROVIDE ( SPI_user_command_read = 0x400621b0 );
|
||||
PROVIDE ( spi_w25q16 = 0x3ffae270 );
|
||||
PROVIDE ( SPIWrite = 0x40062d50 );
|
||||
/* This is static function, but can be used, not generated by script*/
|
||||
PROVIDE ( SPI_write_enable = 0x40062320 );
|
||||
PROVIDE ( SPI_Write_Encrypt_Disable = 0x40062e60 );
|
||||
PROVIDE ( SPI_Write_Encrypt_Enable = 0x40062df4 );
|
||||
/* This is static function, but can be used, not generated by script*/
|
||||
PROVIDE ( SPI_write_status = 0x400622f0 );
|
||||
PROVIDE ( sprintf = 0x40056c08 );
|
||||
PROVIDE ( _sprintf_r = 0x40056bbc );
|
||||
PROVIDE ( __sprint_r = 0x400577e4 );
|
||||
@ -1826,4 +1836,4 @@ PROVIDE ( _xtos_unhandled_exception = 0x4000c024 );
|
||||
PROVIDE ( _xtos_unhandled_interrupt = 0x4000c01c );
|
||||
PROVIDE ( _xtos_vpri_enabled = 0x3ffe0654 );
|
||||
|
||||
PROVIDE ( I2S0 = 0x6000F000 );
|
||||
PROVIDE ( I2S0 = 0x6000F000 );
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit b95a359c344cd052f45e3c38515e4613dd29f298
|
||||
Subproject commit e793e8ac04cae3a5ca87bbccc46021a93288df05
|
@ -44,10 +44,17 @@ void _free_r(struct _reent *r, void* ptr) {
|
||||
return vPortFree(ptr);
|
||||
}
|
||||
|
||||
// TODO: improve realloc to grow buffer in place if possible
|
||||
void* _realloc_r(struct _reent *r, void* ptr, size_t size) {
|
||||
void* new_chunk = pvPortMalloc(size);
|
||||
if (new_chunk) {
|
||||
void* new_chunk;
|
||||
if (size == 0) {
|
||||
if (ptr) {
|
||||
vPortFree(ptr);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
new_chunk = pvPortMalloc(size);
|
||||
if (new_chunk && ptr) {
|
||||
memcpy(new_chunk, ptr, size);
|
||||
vPortFree(ptr);
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
@ -26,9 +27,12 @@
|
||||
|
||||
#if CONFIG_WIFI_ENABLED
|
||||
|
||||
static wifi_startup_cb_t startup_cb;
|
||||
static bool wifi_startup_flag = false;
|
||||
|
||||
#define WIFI_DEBUG(...)
|
||||
static wifi_startup_cb_t startup_cb;
|
||||
static void *startup_ctx;
|
||||
|
||||
#define WIFI_DEBUG(...)
|
||||
#define WIFI_API_CALL_CHECK(info, api_call, ret) \
|
||||
do{\
|
||||
esp_err_t __err = (api_call);\
|
||||
@ -54,7 +58,7 @@ static void esp_wifi_task(void *pvParameters)
|
||||
}
|
||||
|
||||
if (startup_cb) {
|
||||
err = (*startup_cb)();
|
||||
err = (*startup_cb)(startup_ctx);
|
||||
if (err != ESP_OK) {
|
||||
WIFI_DEBUG("startup_cb fail, ret=%d\n", err);
|
||||
break;
|
||||
@ -71,7 +75,7 @@ static void esp_wifi_task(void *pvParameters)
|
||||
wifi_mode_t mode;
|
||||
bool auto_connect;
|
||||
err = esp_wifi_get_mode(&mode);
|
||||
if (err != ESP_OK){
|
||||
if (err != ESP_OK) {
|
||||
WIFI_DEBUG("esp_wifi_get_mode fail, ret=%d\n", err);
|
||||
}
|
||||
|
||||
@ -94,9 +98,17 @@ static void esp_wifi_task(void *pvParameters)
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
void esp_wifi_startup(wifi_startup_cb_t cb)
|
||||
esp_err_t esp_wifi_startup(wifi_startup_cb_t cb, void *ctx)
|
||||
{
|
||||
if (wifi_startup_flag) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
startup_cb = cb;
|
||||
startup_ctx = ctx;
|
||||
|
||||
xTaskCreatePinnedToCore(esp_wifi_task, "wifiTask", 4096, NULL, 5, NULL, 0);// TODO: rearrange task priority
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif
|
||||
|
@ -11,19 +11,23 @@ PYTHON ?= $(call dequote,$(CONFIG_PYTHON))
|
||||
# to invoke esptool.py (with or without serial port args)
|
||||
#
|
||||
# NB: esptool.py lives in the sdk/bin directory not the component directory
|
||||
ESPTOOLPY := $(PYTHON) $(IDF_PATH)/bin/esptool.py --chip esp32
|
||||
ESPTOOLPY_SRC := $(COMPONENT_PATH)/esptool/esptool.py
|
||||
ESPTOOLPY := $(PYTHON) $(ESPTOOLPY_SRC) --chip esp32
|
||||
ESPTOOLPY_SERIAL := $(ESPTOOLPY) --port $(ESPPORT) --baud $(ESPBAUD)
|
||||
|
||||
ESPTOOLPY_WRITE_FLASH=$(ESPTOOLPY_SERIAL) write_flash $(if $(CONFIG_ESPTOOLPY_COMPRESSED),-z) --flash_mode $(ESPFLASHMODE) --flash_freq $(ESPFLASHFREQ)
|
||||
# the no-stub argument is temporary until esptool.py fully supports compressed uploads
|
||||
ESPTOOLPY_WRITE_FLASH=$(ESPTOOLPY_SERIAL) $(if $(CONFIG_ESPTOOLPY_COMPRESSED),--no-stub) write_flash $(if $(CONFIG_ESPTOOLPY_COMPRESSED),-z) --flash_mode $(ESPFLASHMODE) --flash_freq $(ESPFLASHFREQ)
|
||||
|
||||
ESPTOOL_ALL_FLASH_ARGS += $(CONFIG_APP_OFFSET) $(APP_BIN)
|
||||
|
||||
$(APP_BIN): $(APP_ELF)
|
||||
$(APP_BIN): $(APP_ELF) $(ESPTOOLPY_SRC)
|
||||
$(Q) $(ESPTOOLPY) elf2image --flash_mode $(ESPFLASHMODE) --flash_freq $(ESPFLASHFREQ) -o $@ $<
|
||||
|
||||
flash: all_binaries
|
||||
flash: all_binaries $(ESPTOOLPY_SRC)
|
||||
@echo "Flashing project app to $(CONFIG_APP_OFFSET)..."
|
||||
$(Q) $(ESPTOOLPY_WRITE_FLASH) $(ESPTOOL_ALL_FLASH_ARGS)
|
||||
|
||||
app-flash: $(APP_BIN)
|
||||
app-flash: $(APP_BIN) $(ESPTOOLPY_SRC)
|
||||
$(Q) $(ESPTOOLPY_WRITE_FLASH) $(CONFIG_APP_OFFSET) $(APP_BIN)
|
||||
|
||||
$(eval $(call SubmoduleRequiredForFiles,$(ESPTOOLPY_SRC)))
|
||||
|
1
components/esptool_py/esptool
Submodule
1
components/esptool_py/esptool
Submodule
@ -0,0 +1 @@
|
||||
Subproject commit 7c84dd433512bac80e4c01c569e42b4fe76646a7
|
@ -6,4 +6,4 @@ COMPONENT_ADD_LDFLAGS = -l$(COMPONENT_NAME) -Wl,--undefined=uxTopUsedPriority
|
||||
COMPONENT_ADD_INCLUDEDIRS := include
|
||||
COMPONENT_PRIV_INCLUDEDIRS := include/freertos
|
||||
|
||||
include $(IDF_PATH)/make/component.mk
|
||||
include $(IDF_PATH)/make/component_common.mk
|
@ -167,6 +167,9 @@ typedef struct {
|
||||
#define portDISABLE_INTERRUPTS() do { XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL); portbenchmarkINTERRUPT_DISABLE(); } while (0)
|
||||
#define portENABLE_INTERRUPTS() do { portbenchmarkINTERRUPT_RESTORE(0); XTOS_SET_INTLEVEL(0); } while (0)
|
||||
|
||||
#define portASSERT_IF_IN_ISR() vPortAssertIfInISR()
|
||||
void vPortAssertIfInISR();
|
||||
|
||||
#define portCRITICAL_NESTING_IN_TCB 1
|
||||
|
||||
/*
|
||||
@ -213,6 +216,7 @@ portBASE_TYPE vPortCPUReleaseMutex(portMUX_TYPE *mux);
|
||||
|
||||
// Cleaner and preferred solution allows nested interrupts disabling and restoring via local registers or stack.
|
||||
// They can be called from interrupts too.
|
||||
//NOT SMP-COMPATIBLE! Use only if all you want is to disable the interrupts locally!
|
||||
static inline unsigned portENTER_CRITICAL_NESTED() { unsigned state = XTOS_SET_INTLEVEL(XCHAL_EXCM_LEVEL); portbenchmarkINTERRUPT_DISABLE(); return state; }
|
||||
#define portEXIT_CRITICAL_NESTED(state) do { portbenchmarkINTERRUPT_RESTORE(state); XTOS_RESTORE_JUST_INTLEVEL(state); } while (0)
|
||||
|
||||
|
@ -248,14 +248,17 @@ void vPortStoreTaskMPUSettings( xMPU_SETTINGS *xMPUSettings, const struct xMEMOR
|
||||
#endif
|
||||
|
||||
|
||||
void vPortAssertIfInISR()
|
||||
{
|
||||
configASSERT(port_interruptNesting[xPortGetCoreID()]==0)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Wrapper for the Xtensa compare-and-set instruction. This subroutine will atomically compare
|
||||
* *mux to compare, and if it's the same, will set *mux to set. It will return the old value
|
||||
* of *addr.
|
||||
*
|
||||
* Note: the NOPs are needed on the ESP31 processor but superfluous on the ESP32.
|
||||
*
|
||||
* Warning: From the ISA docs: in some (unspecified) cases, the s32c1i instruction may return the
|
||||
* *bitwise inverse* of the old mem if the mem wasn't written. This doesn't seem to happen on the
|
||||
* ESP32, though. (Would show up directly if it did because the magic wouldn't match.)
|
||||
|
@ -163,6 +163,7 @@ typedef struct tskTaskControlBlock
|
||||
|
||||
#if ( portCRITICAL_NESTING_IN_TCB == 1 )
|
||||
UBaseType_t uxCriticalNesting; /*< Holds the critical section nesting depth for ports that do not maintain their own count in the port layer. */
|
||||
uint32_t uxOldInterruptState; /*< Interrupt state before the outer taskEnterCritical was called */
|
||||
#endif
|
||||
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
@ -2595,8 +2596,7 @@ BaseType_t xReturn;
|
||||
|
||||
/* THIS FUNCTION MUST BE CALLED FROM A CRITICAL SECTION. It can also be
|
||||
called from a critical section within an ISR. */
|
||||
//That makes the taskENTER_CRITICALs here unnecessary, right? -JD
|
||||
// taskENTER_CRITICAL(&xTaskQueueMutex);
|
||||
taskENTER_CRITICAL_ISR(&xTaskQueueMutex);
|
||||
/* The event list is sorted in priority order, so the first in the list can
|
||||
be removed as it is known to be the highest priority. Remove the TCB from
|
||||
the delayed list, and add it to the ready list.
|
||||
@ -2654,7 +2654,7 @@ BaseType_t xReturn;
|
||||
prvResetNextTaskUnblockTime();
|
||||
}
|
||||
#endif
|
||||
// taskEXIT_CRITICAL(&xTaskQueueMutex);
|
||||
taskEXIT_CRITICAL_ISR(&xTaskQueueMutex);
|
||||
|
||||
return xReturn;
|
||||
}
|
||||
@ -3614,6 +3614,7 @@ In fact, nothing below this line has/is.
|
||||
{
|
||||
if( pxTCB->uxPriority < pxCurrentTCB[ xPortGetCoreID() ]->uxPriority )
|
||||
{
|
||||
taskENTER_CRITICAL(&xTaskQueueMutex);
|
||||
/* Adjust the mutex holder state to account for its new
|
||||
priority. Only reset the event list item value if the value is
|
||||
not being used for anything else. */
|
||||
@ -3649,6 +3650,8 @@ In fact, nothing below this line has/is.
|
||||
pxTCB->uxPriority = pxCurrentTCB[ xPortGetCoreID() ]->uxPriority;
|
||||
}
|
||||
|
||||
taskEXIT_CRITICAL(&xTaskQueueMutex);
|
||||
|
||||
traceTASK_PRIORITY_INHERIT( pxTCB, pxCurrentTCB[ xPortGetCoreID() ]->uxPriority );
|
||||
}
|
||||
else
|
||||
@ -3686,6 +3689,7 @@ In fact, nothing below this line has/is.
|
||||
/* Only disinherit if no other mutexes are held. */
|
||||
if( pxTCB->uxMutexesHeld == ( UBaseType_t ) 0 )
|
||||
{
|
||||
taskENTER_CRITICAL(&xTaskQueueMutex);
|
||||
/* A task can only have an inhertied priority if it holds
|
||||
the mutex. If the mutex is held by a task then it cannot be
|
||||
given from an interrupt, and if a mutex is given by the
|
||||
@ -3720,6 +3724,7 @@ In fact, nothing below this line has/is.
|
||||
switch should occur when the last mutex is returned whether
|
||||
a task is waiting on it or not. */
|
||||
xReturn = pdTRUE;
|
||||
taskEXIT_CRITICAL(&xTaskQueueMutex);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -3761,7 +3766,14 @@ scheduler will re-enable the interrupts instead. */
|
||||
void vTaskEnterCritical( portMUX_TYPE *mux )
|
||||
#endif
|
||||
{
|
||||
portDISABLE_INTERRUPTS();
|
||||
BaseType_t oldInterruptLevel=0;
|
||||
if( xSchedulerRunning != pdFALSE )
|
||||
{
|
||||
//Interrupts may already be disabled (because we're doing this recursively) but we can't get the interrupt level after
|
||||
//vPortCPUAquireMutex, because it also may mess with interrupts. Get it here first, then later figure out if we're nesting
|
||||
//and save for real there.
|
||||
oldInterruptLevel=portENTER_CRITICAL_NESTED();
|
||||
}
|
||||
#ifdef CONFIG_FREERTOS_PORTMUX_DEBUG
|
||||
vPortCPUAcquireMutex( mux, function, line );
|
||||
#else
|
||||
@ -3772,16 +3784,30 @@ scheduler will re-enable the interrupts instead. */
|
||||
{
|
||||
( pxCurrentTCB[ xPortGetCoreID() ]->uxCriticalNesting )++;
|
||||
|
||||
/* This is not the interrupt safe version of the enter critical
|
||||
if( xSchedulerRunning != pdFALSE && pxCurrentTCB[ xPortGetCoreID() ]->uxCriticalNesting == 1 )
|
||||
{
|
||||
//This is the first time we get called. Save original interrupt level.
|
||||
pxCurrentTCB[ xPortGetCoreID() ]->uxOldInterruptState=oldInterruptLevel;
|
||||
}
|
||||
|
||||
/* Original FreeRTOS comment, saved for reference:
|
||||
This is not the interrupt safe version of the enter critical
|
||||
function so assert() if it is being called from an interrupt
|
||||
context. Only API functions that end in "FromISR" can be used in an
|
||||
interrupt. Only assert if the critical nesting count is 1 to
|
||||
protect against recursive calls if the assert function also uses a
|
||||
critical section. */
|
||||
|
||||
/* DISABLED in the esp32 port - because of SMP, vTaskEnterCritical
|
||||
has to be used in way more places than before, and some are called
|
||||
both from ISR as well as non-ISR code, thus we re-organized
|
||||
vTaskEnterCritical to also work in ISRs. */
|
||||
#if 0
|
||||
if( pxCurrentTCB[ xPortGetCoreID() ]->uxCriticalNesting == 1 )
|
||||
{
|
||||
portASSERT_IF_IN_ISR();
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
else
|
||||
@ -3814,7 +3840,7 @@ scheduler will re-enable the interrupts instead. */
|
||||
|
||||
if( pxCurrentTCB[ xPortGetCoreID() ]->uxCriticalNesting == 0U )
|
||||
{
|
||||
portENABLE_INTERRUPTS();
|
||||
portEXIT_CRITICAL_NESTED(pxCurrentTCB[ xPortGetCoreID() ]->uxOldInterruptState);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -388,19 +388,30 @@ static void lwip_socket_drop_registered_memberships(int s);
|
||||
#endif /* LWIP_IGMP */
|
||||
|
||||
#ifdef LWIP_ESP8266
|
||||
extern size_t system_get_free_heap_size(void);
|
||||
|
||||
#define DELAY_WHEN_MEMORY_NOT_ENOUGH() \
|
||||
do{\
|
||||
uint8_t _wait_delay = 0;\
|
||||
while (system_get_free_heap_size() < HEAP_HIGHWAT){\
|
||||
vTaskDelay(_wait_delay/portTICK_RATE_MS);\
|
||||
if (_wait_delay < 64) _wait_delay *= 2;\
|
||||
}\
|
||||
}while(0)
|
||||
/* Since esp_wifi_tx_is_stop/system_get_free_heap_size are not an public wifi API, so extern them here*/
|
||||
extern size_t system_get_free_heap_size(void);
|
||||
extern bool esp_wifi_tx_is_stop(void);
|
||||
|
||||
/* Please be notified that this flow control is just a workaround for fixing wifi Q full issue.
|
||||
* Under UDP/TCP pressure test, we found that the sockets may cause wifi tx queue full if the socket
|
||||
* sending speed is faster than the wifi sending speed, it will finally cause the packet to be dropped
|
||||
* in wifi layer, it's not acceptable in some application. That's why we introdue the tx flow control here.
|
||||
* However, current solution is just a workaround, we need to consider the return value of wifi tx interface,
|
||||
* and feedback the return value to lwip and let lwip do the flow control itself.
|
||||
*/
|
||||
static inline void esp32_tx_flow_ctrl(void)
|
||||
{
|
||||
uint8_t _wait_delay = 0;
|
||||
|
||||
while ((system_get_free_heap_size() < HEAP_HIGHWAT) || esp_wifi_tx_is_stop()){
|
||||
vTaskDelay(_wait_delay/portTICK_RATE_MS);
|
||||
if (_wait_delay < 64) _wait_delay *= 2;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
#define DELAY_WHEN_MEMORY_NOT_ENOUGH()
|
||||
#define esp32_tx_flow_ctrl()
|
||||
#endif
|
||||
|
||||
/** The global array of available sockets */
|
||||
@ -1219,7 +1230,7 @@ lwip_send(int s, const void *data, size_t size, int flags)
|
||||
#endif /* (LWIP_UDP || LWIP_RAW) */
|
||||
}
|
||||
|
||||
DELAY_WHEN_MEMORY_NOT_ENOUGH();
|
||||
esp32_tx_flow_ctrl();
|
||||
|
||||
write_flags = NETCONN_COPY |
|
||||
((flags & MSG_MORE) ? NETCONN_MORE : 0) |
|
||||
@ -1402,7 +1413,7 @@ lwip_sendto(int s, const void *data, size_t size, int flags,
|
||||
#endif /* LWIP_TCP */
|
||||
}
|
||||
|
||||
DELAY_WHEN_MEMORY_NOT_ENOUGH();
|
||||
esp32_tx_flow_ctrl();
|
||||
|
||||
if ((to != NULL) && !SOCK_ADDR_TYPE_MATCH(to, sock)) {
|
||||
/* sockaddr does not match socket type (IPv4/IPv6) */
|
||||
|
@ -6,6 +6,6 @@ COMPONENT_ADD_INCLUDEDIRS := include/lwip include/lwip/port
|
||||
|
||||
COMPONENT_SRCDIRS := api apps/sntp apps core/ipv4 core/ipv6 core netif port/freertos port/netif port
|
||||
|
||||
EXTRA_CFLAGS := -Wno-error=address -Waddress -DLWIP_ESP8266
|
||||
EXTRA_CFLAGS := -Wno-error=address -Waddress
|
||||
|
||||
include $(IDF_PATH)/make/component.mk
|
||||
include $(IDF_PATH)/make/component_common.mk
|
@ -712,10 +712,10 @@ void dhcp_cleanup(struct netif *netif)
|
||||
|
||||
/* Espressif add start. */
|
||||
|
||||
/** Set callback for dhcp, reversed parameter for future use.
|
||||
/** Set callback for dhcp, reserved parameter for future use.
|
||||
*
|
||||
* @param netif the netif from which to remove the struct dhcp
|
||||
* @param cb callback for chcp
|
||||
* @param cb callback for dhcp
|
||||
*/
|
||||
void dhcp_set_cb(struct netif *netif, void (*cb)(void))
|
||||
{
|
||||
|
@ -68,7 +68,5 @@ void sys_delay_ms(uint32_t ms);
|
||||
sys_sem_t* sys_thread_sem_init(void);
|
||||
void sys_thread_sem_deinit(void);
|
||||
sys_sem_t* sys_thread_sem_get(void);
|
||||
|
||||
|
||||
#endif /* __SYS_ARCH_H__ */
|
||||
|
||||
|
@ -34,6 +34,8 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
/* Enable all Espressif-only options */
|
||||
#define LWIP_ESP8266
|
||||
|
||||
/*
|
||||
-----------------------------------------------
|
||||
|
@ -5,4 +5,4 @@ define COMPONENT_BUILDRECIPE
|
||||
#Nothing to do; this does not generate a library.
|
||||
endef
|
||||
|
||||
include $(IDF_PATH)/make/component.mk
|
||||
include $(IDF_PATH)/make/component_common.mk
|
@ -6,4 +6,4 @@ COMPONENT_ADD_INCLUDEDIRS := include
|
||||
|
||||
COMPONENT_SRCDIRS := src
|
||||
|
||||
include $(IDF_PATH)/make/component.mk
|
||||
include $(IDF_PATH)/make/component_common.mk
|
@ -9,7 +9,7 @@
|
||||
.PHONY: partition_table partition_table-flash partition_table-clean
|
||||
|
||||
# NB: gen_esp32part.py lives in the sdk/bin/ dir not component dir
|
||||
GEN_ESP32PART := $(PYTHON) $(IDF_PATH)/bin/gen_esp32part.py -q
|
||||
GEN_ESP32PART := $(PYTHON) $(COMPONENT_PATH)/gen_esp32part.py -q
|
||||
|
||||
# Path to partition CSV file is relative to project path for custom
|
||||
# partition CSV files, but relative to component dir otherwise.$
|
||||
|
@ -1,3 +0,0 @@
|
||||
COMPONENT_ADD_INCLUDEDIRS := include
|
||||
|
||||
include $(IDF_PATH)/make/component.mk
|
3
components/spi_flash/component.mk
Executable file
3
components/spi_flash/component.mk
Executable file
@ -0,0 +1,3 @@
|
||||
COMPONENT_ADD_INCLUDEDIRS := include
|
||||
|
||||
include $(IDF_PATH)/make/component_common.mk
|
@ -12,15 +12,217 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <freertos/FreeRTOS.h>
|
||||
#include <freertos/task.h>
|
||||
#include <freertos/semphr.h>
|
||||
|
||||
#include <esp_spi_flash.h>
|
||||
#include <rom/spi_flash.h>
|
||||
#include <rom/cache.h>
|
||||
#include <esp_attr.h>
|
||||
#include <soc/soc.h>
|
||||
#include <soc/dport_reg.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "esp_ipc.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_spi_flash.h"
|
||||
|
||||
|
||||
/*
|
||||
Driver for SPI flash read/write/erase operations
|
||||
|
||||
In order to perform some flash operations, we need to make sure both CPUs
|
||||
are not running any code from flash for the duration of the flash operation.
|
||||
In a single-core setup this is easy: we disable interrupts/scheduler and do
|
||||
the flash operation. In the dual-core setup this is slightly more complicated.
|
||||
We need to make sure that the other CPU doesn't run any code from flash.
|
||||
|
||||
|
||||
When SPI flash API is called on CPU A (can be PRO or APP), we start
|
||||
spi_flash_op_block_func function on CPU B using esp_ipc_call API. This API
|
||||
wakes up high priority task on CPU B and tells it to execute given function,
|
||||
in this case spi_flash_op_block_func. This function disables cache on CPU B and
|
||||
signals that cache is disabled by setting s_flash_op_can_start flag.
|
||||
Then the task on CPU A disables cache as well, and proceeds to execute flash
|
||||
operation.
|
||||
|
||||
While flash operation is running, interrupts can still run on CPU B.
|
||||
We assume that all interrupt code is placed into RAM.
|
||||
|
||||
Once flash operation is complete, function on CPU A sets another flag,
|
||||
s_flash_op_complete, to let the task on CPU B know that it can re-enable
|
||||
cache and release the CPU. Then the function on CPU A re-enables the cache on
|
||||
CPU A as well and returns control to the calling code.
|
||||
|
||||
Additionally, all API functions are protected with a mutex (s_flash_op_mutex).
|
||||
|
||||
In a single core environment (CONFIG_FREERTOS_UNICORE enabled), we simply
|
||||
disable both caches, no inter-CPU communication takes place.
|
||||
*/
|
||||
|
||||
static esp_err_t spi_flash_translate_rc(SpiFlashOpResult rc);
|
||||
static void IRAM_ATTR spi_flash_disable_cache(uint32_t cpuid, uint32_t* saved_state);
|
||||
static void IRAM_ATTR spi_flash_restore_cache(uint32_t cpuid, uint32_t saved_state);
|
||||
|
||||
static uint32_t s_flash_op_cache_state[2];
|
||||
|
||||
#ifndef CONFIG_FREERTOS_UNICORE
|
||||
static SemaphoreHandle_t s_flash_op_mutex;
|
||||
static bool s_flash_op_can_start = false;
|
||||
static bool s_flash_op_complete = false;
|
||||
#endif //CONFIG_FREERTOS_UNICORE
|
||||
|
||||
|
||||
#ifndef CONFIG_FREERTOS_UNICORE
|
||||
|
||||
static void IRAM_ATTR spi_flash_op_block_func(void* arg)
|
||||
{
|
||||
// Disable scheduler on this CPU
|
||||
vTaskSuspendAll();
|
||||
uint32_t cpuid = (uint32_t) arg;
|
||||
// Disable cache so that flash operation can start
|
||||
spi_flash_disable_cache(cpuid, &s_flash_op_cache_state[cpuid]);
|
||||
s_flash_op_can_start = true;
|
||||
while (!s_flash_op_complete) {
|
||||
// until we have a way to use interrupts for inter-CPU communication,
|
||||
// busy loop here and wait for the other CPU to finish flash operation
|
||||
}
|
||||
// Flash operation is complete, re-enable cache
|
||||
spi_flash_restore_cache(cpuid, s_flash_op_cache_state[cpuid]);
|
||||
// Re-enable scheduler
|
||||
xTaskResumeAll();
|
||||
}
|
||||
|
||||
void spi_flash_init()
|
||||
{
|
||||
s_flash_op_mutex = xSemaphoreCreateMutex();
|
||||
}
|
||||
|
||||
static void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu()
|
||||
{
|
||||
// Take the API lock
|
||||
xSemaphoreTake(s_flash_op_mutex, portMAX_DELAY);
|
||||
|
||||
const uint32_t cpuid = xPortGetCoreID();
|
||||
const uint32_t other_cpuid = (cpuid == 0) ? 1 : 0;
|
||||
|
||||
if (xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED) {
|
||||
// Scheduler hasn't been started yet, it means that spi_flash API is being
|
||||
// called from the 2nd stage bootloader or from user_start_cpu0, i.e. from
|
||||
// PRO CPU. APP CPU is either in reset or spinning inside user_start_cpu1,
|
||||
// which is in IRAM. So it is safe to disable cache for the other_cpuid here.
|
||||
assert(other_cpuid == 1);
|
||||
spi_flash_disable_cache(other_cpuid, &s_flash_op_cache_state[other_cpuid]);
|
||||
} else {
|
||||
// Signal to the spi_flash_op_block_task on the other CPU that we need it to
|
||||
// disable cache there and block other tasks from executing.
|
||||
s_flash_op_can_start = false;
|
||||
s_flash_op_complete = false;
|
||||
esp_ipc_call(other_cpuid, &spi_flash_op_block_func, (void*) other_cpuid);
|
||||
while (!s_flash_op_can_start) {
|
||||
// Busy loop and wait for spi_flash_op_block_func to disable cache
|
||||
// on the other CPU
|
||||
}
|
||||
// Disable scheduler on CPU cpuid
|
||||
vTaskSuspendAll();
|
||||
// This is guaranteed to run on CPU <cpuid> because the other CPU is now
|
||||
// occupied by highest priority task
|
||||
assert(xPortGetCoreID() == cpuid);
|
||||
}
|
||||
// Disable cache on this CPU as well
|
||||
spi_flash_disable_cache(cpuid, &s_flash_op_cache_state[cpuid]);
|
||||
}
|
||||
|
||||
static void IRAM_ATTR spi_flash_enable_interrupts_caches_and_other_cpu()
|
||||
{
|
||||
const uint32_t cpuid = xPortGetCoreID();
|
||||
const uint32_t other_cpuid = (cpuid == 0) ? 1 : 0;
|
||||
|
||||
// Re-enable cache on this CPU
|
||||
spi_flash_restore_cache(cpuid, s_flash_op_cache_state[cpuid]);
|
||||
|
||||
if (xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED) {
|
||||
// Scheduler is not running yet — this means we are running on PRO CPU.
|
||||
// other_cpuid is APP CPU, and it is either in reset or is spinning in
|
||||
// user_start_cpu1, which is in IRAM. So we can simply reenable cache.
|
||||
assert(other_cpuid == 1);
|
||||
spi_flash_restore_cache(other_cpuid, s_flash_op_cache_state[other_cpuid]);
|
||||
} else {
|
||||
// Signal to spi_flash_op_block_task that flash operation is complete
|
||||
s_flash_op_complete = true;
|
||||
// Resume tasks on the current CPU
|
||||
xTaskResumeAll();
|
||||
}
|
||||
// Release API lock
|
||||
xSemaphoreGive(s_flash_op_mutex);
|
||||
}
|
||||
|
||||
#else // CONFIG_FREERTOS_UNICORE
|
||||
|
||||
void spi_flash_init()
|
||||
{
|
||||
// No-op in single core mode
|
||||
}
|
||||
|
||||
static void IRAM_ATTR spi_flash_disable_interrupts_caches_and_other_cpu()
|
||||
{
|
||||
vTaskSuspendAll();
|
||||
spi_flash_disable_cache(0, &s_flash_op_cache_state[0]);
|
||||
}
|
||||
|
||||
static void IRAM_ATTR spi_flash_enable_interrupts_caches_and_other_cpu()
|
||||
{
|
||||
spi_flash_restore_cache(0, s_flash_op_cache_state[0]);
|
||||
xTaskResumeAll();
|
||||
}
|
||||
|
||||
#endif // CONFIG_FREERTOS_UNICORE
|
||||
|
||||
|
||||
SpiFlashOpResult IRAM_ATTR spi_flash_unlock()
|
||||
{
|
||||
static bool unlocked = false;
|
||||
if (!unlocked) {
|
||||
SpiFlashOpResult rc = SPIUnlock();
|
||||
if (rc != SPI_FLASH_RESULT_OK) {
|
||||
return rc;
|
||||
}
|
||||
unlocked = true;
|
||||
}
|
||||
return SPI_FLASH_RESULT_OK;
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR spi_flash_erase_sector(uint16_t sec)
|
||||
{
|
||||
spi_flash_disable_interrupts_caches_and_other_cpu();
|
||||
SpiFlashOpResult rc;
|
||||
rc = spi_flash_unlock();
|
||||
if (rc == SPI_FLASH_RESULT_OK) {
|
||||
rc = SPIEraseSector(sec);
|
||||
}
|
||||
spi_flash_enable_interrupts_caches_and_other_cpu();
|
||||
return spi_flash_translate_rc(rc);
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR spi_flash_write(uint32_t dest_addr, const uint32_t *src, uint32_t size)
|
||||
{
|
||||
spi_flash_disable_interrupts_caches_and_other_cpu();
|
||||
SpiFlashOpResult rc;
|
||||
rc = spi_flash_unlock();
|
||||
if (rc == SPI_FLASH_RESULT_OK) {
|
||||
rc = SPIWrite(dest_addr, src, (int32_t) size);
|
||||
}
|
||||
spi_flash_enable_interrupts_caches_and_other_cpu();
|
||||
return spi_flash_translate_rc(rc);
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR spi_flash_read(uint32_t src_addr, uint32_t *dest, uint32_t size)
|
||||
{
|
||||
spi_flash_disable_interrupts_caches_and_other_cpu();
|
||||
SpiFlashOpResult rc;
|
||||
rc = SPIRead(src_addr, dest, (int32_t) size);
|
||||
spi_flash_enable_interrupts_caches_and_other_cpu();
|
||||
return spi_flash_translate_rc(rc);
|
||||
}
|
||||
|
||||
static esp_err_t spi_flash_translate_rc(SpiFlashOpResult rc)
|
||||
{
|
||||
@ -35,72 +237,36 @@ static esp_err_t spi_flash_translate_rc(SpiFlashOpResult rc)
|
||||
}
|
||||
}
|
||||
|
||||
extern void Cache_Flush(int);
|
||||
static const uint32_t cache_mask = DPORT_APP_CACHE_MASK_OPSDRAM | DPORT_APP_CACHE_MASK_DROM0 |
|
||||
DPORT_APP_CACHE_MASK_DRAM1 | DPORT_APP_CACHE_MASK_IROM0 |
|
||||
DPORT_APP_CACHE_MASK_IRAM1 | DPORT_APP_CACHE_MASK_IRAM0;
|
||||
|
||||
static void IRAM_ATTR spi_flash_disable_interrupts_caches_and_app_cpu()
|
||||
static void IRAM_ATTR spi_flash_disable_cache(uint32_t cpuid, uint32_t* saved_state)
|
||||
{
|
||||
vTaskSuspendAll();
|
||||
// SET_PERI_REG_MASK(APPCPU_CTRL_REG_C, DPORT_APPCPU_RUNSTALL);
|
||||
Cache_Read_Disable(0);
|
||||
Cache_Read_Disable(1);
|
||||
}
|
||||
|
||||
static void IRAM_ATTR spi_flash_enable_interrupts_caches_and_app_cpu()
|
||||
{
|
||||
Cache_Read_Enable(0);
|
||||
Cache_Read_Enable(1);
|
||||
// CLEAR_PERI_REG_MASK(APPCPU_CTRL_REG_C, DPORT_APPCPU_RUNSTALL);
|
||||
xTaskResumeAll();
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR spi_flash_erase_sector(uint16_t sec)
|
||||
{
|
||||
spi_flash_disable_interrupts_caches_and_app_cpu();
|
||||
SpiFlashOpResult rc;
|
||||
if (xPortGetCoreID() == 1) {
|
||||
rc = SPI_FLASH_RESULT_ERR;
|
||||
}
|
||||
else {
|
||||
rc = SPIUnlock();
|
||||
if (rc == SPI_FLASH_RESULT_OK) {
|
||||
rc = SPIEraseSector(sec);
|
||||
uint32_t ret = 0;
|
||||
if (cpuid == 0) {
|
||||
ret |= GET_PERI_REG_BITS2(PRO_CACHE_CTRL1_REG, cache_mask, 0);
|
||||
while (GET_PERI_REG_BITS2(PRO_DCACHE_DBUG_REG0, DPORT_PRO_CACHE_STATE, DPORT_PRO_CACHE_STATE_S) != 1) {
|
||||
;
|
||||
}
|
||||
}
|
||||
Cache_Flush(0);
|
||||
Cache_Flush(1);
|
||||
spi_flash_enable_interrupts_caches_and_app_cpu();
|
||||
return spi_flash_translate_rc(rc);
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR spi_flash_write(uint32_t dest_addr, const uint32_t *src, uint32_t size)
|
||||
{
|
||||
spi_flash_disable_interrupts_caches_and_app_cpu();
|
||||
SpiFlashOpResult rc;
|
||||
if (xPortGetCoreID() == 1) {
|
||||
rc = SPI_FLASH_RESULT_ERR;
|
||||
}
|
||||
else {
|
||||
rc = SPIUnlock();
|
||||
if (rc == SPI_FLASH_RESULT_OK) {
|
||||
rc = SPIWrite(dest_addr, src, (int32_t) size);
|
||||
SET_PERI_REG_BITS(PRO_CACHE_CTRL_REG, 1, 0, DPORT_PRO_CACHE_ENABLE_S);
|
||||
} else {
|
||||
ret |= GET_PERI_REG_BITS2(APP_CACHE_CTRL1_REG, cache_mask, 0);
|
||||
while (GET_PERI_REG_BITS2(APP_DCACHE_DBUG_REG0, DPORT_APP_CACHE_STATE, DPORT_APP_CACHE_STATE_S) != 1) {
|
||||
;
|
||||
}
|
||||
SET_PERI_REG_BITS(APP_CACHE_CTRL_REG, 1, 0, DPORT_APP_CACHE_ENABLE_S);
|
||||
}
|
||||
Cache_Flush(0);
|
||||
Cache_Flush(1);
|
||||
spi_flash_enable_interrupts_caches_and_app_cpu();
|
||||
return spi_flash_translate_rc(rc);
|
||||
*saved_state = ret;
|
||||
}
|
||||
|
||||
esp_err_t IRAM_ATTR spi_flash_read(uint32_t src_addr, uint32_t *dest, uint32_t size)
|
||||
static void IRAM_ATTR spi_flash_restore_cache(uint32_t cpuid, uint32_t saved_state)
|
||||
{
|
||||
spi_flash_disable_interrupts_caches_and_app_cpu();
|
||||
SpiFlashOpResult rc;
|
||||
if (xPortGetCoreID() == 1) {
|
||||
rc = SPI_FLASH_RESULT_ERR;
|
||||
if (cpuid == 0) {
|
||||
SET_PERI_REG_BITS(PRO_CACHE_CTRL_REG, 1, 1, DPORT_PRO_CACHE_ENABLE_S);
|
||||
SET_PERI_REG_BITS(PRO_CACHE_CTRL1_REG, cache_mask, saved_state, 0);
|
||||
} else {
|
||||
SET_PERI_REG_BITS(APP_CACHE_CTRL_REG, 1, 1, DPORT_APP_CACHE_ENABLE_S);
|
||||
SET_PERI_REG_BITS(APP_CACHE_CTRL1_REG, cache_mask, saved_state, 0);
|
||||
}
|
||||
else {
|
||||
rc = SPIRead(src_addr, dest, (int32_t) size);
|
||||
}
|
||||
spi_flash_enable_interrupts_caches_and_app_cpu();
|
||||
return spi_flash_translate_rc(rc);
|
||||
}
|
||||
|
@ -28,6 +28,15 @@ extern "C" {
|
||||
|
||||
#define SPI_FLASH_SEC_SIZE 4096 /**< SPI Flash sector size */
|
||||
|
||||
/**
|
||||
* @brief Initialize SPI flash access driver
|
||||
*
|
||||
* This function must be called exactly once, before any other
|
||||
* spi_flash_* functions are called.
|
||||
*
|
||||
*/
|
||||
void spi_flash_init();
|
||||
|
||||
/**
|
||||
* @brief Erase the Flash sector.
|
||||
*
|
||||
|
@ -1,7 +0,0 @@
|
||||
#
|
||||
# Component Makefile
|
||||
#
|
||||
|
||||
EXTRA_CFLAGS := -DLWIP_ESP8266
|
||||
|
||||
include $(IDF_PATH)/make/component.mk
|
5
components/tcpip_adapter/component.mk
Executable file
5
components/tcpip_adapter/component.mk
Executable file
@ -0,0 +1,5 @@
|
||||
#
|
||||
# Component Makefile
|
||||
#
|
||||
|
||||
include $(IDF_PATH)/make/component_common.mk
|
@ -454,7 +454,7 @@ static void tcpip_adapter_dhcpc_cb(void)
|
||||
ip4_addr_set(&ip_info->gw, ip_2_ip4(&netif->gw));
|
||||
|
||||
//notify event
|
||||
evt.event_id = SYSTEM_EVENT_STA_GOTIP;
|
||||
evt.event_id = SYSTEM_EVENT_STA_GOT_IP;
|
||||
memcpy(&evt.event_info.got_ip.ip_info, ip_info, sizeof(tcpip_adapter_ip_info_t));
|
||||
|
||||
esp_event_send(&evt);
|
||||
|
302
docs/build_system.rst
Normal file
302
docs/build_system.rst
Normal file
@ -0,0 +1,302 @@
|
||||
Build System
|
||||
------------
|
||||
|
||||
This document explains the Espressif IoT Development Framework build system and the
|
||||
concept of "components"
|
||||
|
||||
Read this document if you want to know how to organise a new ESP-IDF project.
|
||||
|
||||
We recommend using the esp-idf-template_ project as a starting point for your project.
|
||||
|
||||
Overview
|
||||
========
|
||||
|
||||
An ESP-IDF project can be seen as an almagation of a number of components.
|
||||
For example, for a webserver that shows the current humidity, we would
|
||||
have:
|
||||
|
||||
- The ESP32 base libraries (libc, rom bindings etc)
|
||||
- The WiFi drivers
|
||||
- A TCP/IP stack
|
||||
- The FreeRTOS operating system
|
||||
- A webserver
|
||||
- A driver for an humidity sensor
|
||||
- Main code tying it all together
|
||||
|
||||
ESP-IDF makes these components explicit and configurable. To do that, when a project
|
||||
is compiled, the build environment will look up all the components in the
|
||||
ESP-IDF directories, the project directories and optionally custom other component
|
||||
directories. It then allows the user to configure compile-time options using
|
||||
a friendly text-based menu system to customize the ESP-IDF as well as other components
|
||||
to the requirements of the project. After the components are customized, the
|
||||
build process will compile everything into an output file, which can then be uploaded
|
||||
into a board in a way that can also be defined by components.
|
||||
|
||||
A project in this sense is defined as a directory under which all the files required
|
||||
to build it live, excluding the ESP-IDF files and the toolchain. A simple project
|
||||
tree might look like this::
|
||||
|
||||
- myProject/ - build/
|
||||
- components/ - component1/ - component.mk
|
||||
- Kconfig
|
||||
- src1.c
|
||||
- component2/ - component.mk
|
||||
- Kconfig
|
||||
- src1.c
|
||||
- main/ - src1.c
|
||||
- src2.c
|
||||
- Makefile
|
||||
|
||||
As we can see, a project consists of a components/ subdirectory containing its
|
||||
components as well as one or more directories containing the project-specific
|
||||
sources; by default a single directory called 'main' is assumed. The project
|
||||
directory will also have a Makefile where the projects name as well as optionally
|
||||
other options are defined. After compilation, the project directory will contain
|
||||
a 'build'-directory containing all of the objects, libraries and other generated
|
||||
files as well as the final binary.
|
||||
|
||||
Components also have a custom makefile - ``component.mk``. This contains various definititions
|
||||
influencing the build process of the component as well as the project it's used
|
||||
in. Components may also include a Kconfig file defining the compile-time options that are
|
||||
settable by means of the menu system.
|
||||
|
||||
Project makefile variables that can be set by the programmer::
|
||||
|
||||
PROJECT_NAME: Mandatory. Name for the project
|
||||
BUILD_DIR_BASE: Set the directory where all objects/libraries/binaries end up in.
|
||||
Defaults to $(PROJECT_PATH)/build
|
||||
COMPONENT_DIRS: Search path for components. Defaults to the component/ directories
|
||||
in the ESP-IDF path and the project path.
|
||||
COMPONENTS: A list of component names. Defaults to all the component found in the
|
||||
COMPONENT_DIRS directory
|
||||
EXTRA_COMPONENT_DIRS: Defaults to unset. Use this to add directories to the default
|
||||
COMPONENT_DIRS.
|
||||
SRCDIRS: Directories under the project dir containing project-specific sources.
|
||||
Defaults to 'main'. These are treated as 'lite' components: they do not have
|
||||
include directories that are passed to the compilation pass of all components and
|
||||
they do not have a Kconfig option.
|
||||
|
||||
Component makefile variables that can be set by the programmer::
|
||||
|
||||
COMPONENT_ADD_INCLUDEDIRS: Relative path to include directories to be added to
|
||||
the entire project
|
||||
COMPONENT_PRIV_INCLUDEDIRS: Relative path to include directories that are only used
|
||||
when compiling this specific component
|
||||
COMPONENT_DEPENDS: Names of any components that need to be compiled before this component.
|
||||
COMPONENT_ADD_LDFLAGS: Ld flags to add for this project. Defaults to -l$(COMPONENT_NAME).
|
||||
Add libraries etc in the current directory as $(abspath libwhatever.a)
|
||||
COMPONENT_EXTRA_INCLUDES: Any extra include paths. These will be prefixed with '-I' and
|
||||
passed to the compiler; please put absolute paths here.
|
||||
COMPONENT_SRCDIRS: Relative directories to look in for sources. Defaults to '.', the current
|
||||
directory (the root of the component) only. Use this to specify any subdirectories. Note
|
||||
that specifying this overwrites the default action of compiling everything in the
|
||||
components root dir; to keep this behaviour please also add '.' as a directory in this
|
||||
list.
|
||||
COMPONENT_OBJS: Object files to compile. Defaults to the .o variants of all .c and .S files
|
||||
that are found in COMPONENT_SRCDIRS.
|
||||
COMPONENT_EXTRA_CLEAN: Files that are generated using rules in the components Makefile
|
||||
that also need to be cleaned
|
||||
COMPONENT_BUILDRECIPE: Recipe to build the component. Optional. Defaults to building all
|
||||
COMPONENT_OBJS and linking them into lib(componentname).a
|
||||
COMPONENT_CLEANRECIPE: Recipe to clean the component. Optional. Defaults to removing
|
||||
all built objects and libraries.
|
||||
COMPONENT_BUILD_DIR: Equals the cwd of the component build, which is the build dir
|
||||
of the component (where all the .o etc files should be created).
|
||||
|
||||
These variables are already set early on in the Makefile and the values in it will
|
||||
be usable in component or project Makefiles::
|
||||
|
||||
CC, LD, AR, OBJCOPY: Xtensa gcc tools
|
||||
HOSTCC, HOSTLD etc: Host gcc tools
|
||||
LDFLAGS, CFLAGS: Set to usable values as defined in ESP-IDF Makefile
|
||||
PROJECT_NAME: Name of the project, as set in project makefile
|
||||
PROJECT_PATH: Path to the root of the project folder
|
||||
COMPONENTS: Name of the components to be included
|
||||
CONFIG_*: All values set by 'make menuconfig' have corresponding Makefile variables.
|
||||
|
||||
For components, there also are these defines::
|
||||
|
||||
COMPONENT_PATH: Absolute path to the root of the source tree of the component we're
|
||||
compiling
|
||||
COMPONENT_LIBRARY: The full path to the static library the components compilation pass
|
||||
is supposed to generate
|
||||
|
||||
Make Process
|
||||
------------
|
||||
|
||||
The Make process is always invoked from the project directory by the
|
||||
user; invoking it anywhere else gives an error. This is what happens if
|
||||
we build a binary:
|
||||
|
||||
The Makefile first determines how it was included. It figures out
|
||||
various paths as well as the components available to it. It will also
|
||||
collect the ldflags and includes that the components specify they need.
|
||||
It does this by running a dummy make on the components with a "get_variable"
|
||||
target that will output these values.
|
||||
|
||||
The Makefile will then create targets to build the lib*.a libraries of
|
||||
all components and make the elf target depend on this. The main Makefile
|
||||
invokes Make on the componen.mk of each components inside a sub-mke: this way
|
||||
the components have full freedom to do whatever is necessary to build
|
||||
the library without influencing other components. By default, the
|
||||
component.mk includes the utility makefile $(IDF_PATH)/make/component_common.mk.
|
||||
This provides default targets and configurations that will work
|
||||
out-of-the-box for most projects.
|
||||
|
||||
KConfig
|
||||
-------
|
||||
|
||||
Each component can also have a Kconfig file, alongside the component.mk, that contains
|
||||
details to add to "menuconfig" for this component.
|
||||
|
||||
Makefile.projbuild
|
||||
------------------
|
||||
|
||||
For components that have parts that need to be run when building of the
|
||||
project is done, you can create a file called Makefile.projbuild in the
|
||||
component root directory. This file will be included in the main
|
||||
Makefile.
|
||||
|
||||
|
||||
KConfig.projbuild
|
||||
-----------------
|
||||
|
||||
There's an equivalent to Makefile.projbuild for KConfig: if you want to include
|
||||
options at the top-level, not inside the 'components' submenu then create a Kconfig.projbuild and
|
||||
it will be included in the main menu of menuconfig.
|
||||
|
||||
Take good care when (re)defining stuff here: because it's included with all the other
|
||||
.projbuild files, it's possible to overwrite variables or re-declare targets defined in
|
||||
the ESP-IDF makefile/Kconfig and other .projbuild files. It's generally better to just
|
||||
create a KConfig file, if you can.
|
||||
|
||||
|
||||
Writing Component Makefiles
|
||||
---------------------------
|
||||
|
||||
A component consists of a directory which doubles as the name for the
|
||||
component: a component named 'httpd' lives in a directory called 'httpd'
|
||||
Because components usually live under the project directory (although
|
||||
they can also reside in an other folder), the path to this may be
|
||||
something like /home/myuser/projects/myprojects/components/httpd .
|
||||
|
||||
One of the things that most components will have is a component.mk makefile,
|
||||
containing instructions on how to build the component. Because the
|
||||
build environment tries to set reasonable defaults that will work most
|
||||
of the time, component.mk can be very small.
|
||||
|
||||
Simplest component.mk
|
||||
=====================
|
||||
|
||||
At the minimum, component.mk will just include the ESP-IDF component "common" makefile,
|
||||
which adds common component functionality::
|
||||
|
||||
include $(IDF_PATH)/make/component_common.mk
|
||||
|
||||
This will take all the .c and .S files in the component root and compile
|
||||
them into object files, finally linking them into a library.
|
||||
|
||||
|
||||
Adding source directories
|
||||
=========================
|
||||
|
||||
By default, subdirectories are ignored. If your project has sources in subdirectories
|
||||
instead of in the root of the component then you can tell that to the build
|
||||
system by setting COMPONENT_SRCDIRS::
|
||||
|
||||
COMPONENT_SRCDIRS := src1 src2
|
||||
include $(IDF_PATH)/make/component_common.mk
|
||||
|
||||
This will compile all source files in the src1/ and src2/ subdirectories
|
||||
instead.
|
||||
|
||||
Specifying source files
|
||||
=======================
|
||||
|
||||
The standard component.mk logic adds all .S and .c files in the source
|
||||
directories as sources to be compiled unconditionally. It is possible
|
||||
to circumvent that logic and hardcode the objects to be compiled by
|
||||
manually setting the COMPONENT_OBJS variable to the name of the
|
||||
objects that need to be generated::
|
||||
|
||||
COMPONENT_OBJS := file1.o file2.o thing/filea.o thing/fileb.o anotherthing/main.o
|
||||
include $(IDF_PATH)/make/component_common.mk
|
||||
|
||||
|
||||
Adding conditional configuration
|
||||
================================
|
||||
|
||||
The configuration system can be used to conditionally compile some files
|
||||
dependending on the options selected in ``make menuconfig``:
|
||||
|
||||
Kconfig::
|
||||
config FOO_ENABLE_BAR
|
||||
bool "Enable the BAR feature."
|
||||
help
|
||||
This enables the BAR feature of the FOO component.
|
||||
|
||||
Makefile::
|
||||
COMPONENT_OBJS := foo_a.o foo_b.o $(if $(CONFIG_FOO_ENABLE_BAR),foo_bar.o foo_bar_interface.o)
|
||||
include $(IDF_PATH)/make/component_common.mk
|
||||
|
||||
|
||||
Source Code Generation
|
||||
======================
|
||||
|
||||
Some components will have a situation where a source file isn't supplied
|
||||
with the component itself but has to be generated from another file. Say
|
||||
our component has a header file that consists of the converted binary
|
||||
data of a BMP file, converted using a hypothetical tool called bmp2h. The
|
||||
header file is then included in as C source file called graphics_lib.c::
|
||||
|
||||
COMPONENT_EXTRA_CLEAN := logo.h
|
||||
|
||||
graphics_lib.o: logo.h
|
||||
|
||||
logo.h: $(COMPONENT_PATH)/logo.bmp
|
||||
bmp2h -i $^ -o $@
|
||||
|
||||
include $(IDF_PATH)/make/component_common.mk
|
||||
|
||||
In this example, graphics_lib.o and logo.h will be generated in the
|
||||
current directory (the build directory) while logo.bmp comes with the
|
||||
component and resides under the component path. Because logo.h is a
|
||||
generated file, it needs to be cleaned when make clean is called which
|
||||
why it is added to the COMPONENT_EXTRA_CLEAN variable.
|
||||
|
||||
Cosmetic Improvements
|
||||
=====================
|
||||
|
||||
The above example will work just fine, but there's one last cosmetic
|
||||
improvement that can be done. The make system tries to make the make
|
||||
process somewhat easier on the eyes by hiding the commands (unless you
|
||||
run make with the V=1 switch) and this does not do that yet. Here's an
|
||||
improved version that will output in the same style as the rest of the
|
||||
make process::
|
||||
|
||||
COMPONENT_EXTRA_CLEAN := test_tjpgd_logo.h
|
||||
|
||||
graphics_lib.o: logo.h
|
||||
|
||||
logo.h: $(COMPONENT_PATH)/logo.bmp
|
||||
$(summary) BMP2H $@
|
||||
$(Q) bmp2h -i $^ -o $@
|
||||
|
||||
include $(IDF_PATH)/make/component_common.mk
|
||||
|
||||
Fully Overriding The Component Makefile
|
||||
---------------------------------------
|
||||
|
||||
Obviously, there are cases where all these recipes are insufficient for a
|
||||
certain component, for example when the component is basically a wrapper
|
||||
around another third-party component not originally intended to be
|
||||
compiled under this build system. In that case, it's possible to forego
|
||||
the build system entirely by setting COMPONENT_OWNBUILDTARGET and
|
||||
possibly COMPONENT_OWNCLEANTARGET and defining your own build- and clean
|
||||
target. The build target can do anything as long as it creates
|
||||
$(COMPONENT_LIBRARY) for the main file to link into the project binary,
|
||||
and even that is not necessary: if the COMPONENT_ADD_LDFLAGS variable
|
||||
is set, the component can instruct the linker to do anything else as well.
|
||||
|
||||
|
||||
.. _esp-idf-template: https://github.com/espressif/esp-idf-template
|
@ -39,9 +39,9 @@ Project Properties
|
||||
|
||||
*Windows users only, follow these two additional steps:*
|
||||
|
||||
* On the same Environment property page, edit the PATH environment variable and append ``;C:\msys32\usr\bin;C:\msys32\mingw32\bin;C:\msys32\opt\xtensa-esp32-elf\bin`` to the end of the default value. (If you installed msys32 to a different directory then you'll need to change these paths to match.)
|
||||
* On the same Environment property page, edit the PATH environment variable. Delete the existing value and replace it with ``C:\msys32\usr\bin;C:\msys32\mingw32\bin;C:\msys32\opt\xtensa-esp32-elf\bin`` (If you installed msys32 to a different directory then you'll need to change these paths to match).
|
||||
|
||||
* Click on the "C/C++ Build" top-level properties page then uncheck "Use default build command" and enter this for the custom build command: ``bash ${IDF_PATH}/bin/eclipse_windows_make.sh``.
|
||||
* Click on the "C/C++ Build" top-level properties page then uncheck "Use default build command" and enter this for the custom build command: ``bash ${IDF_PATH}/tools/windows/eclipse_make.sh``.
|
||||
|
||||
*All users, continue with these steps:*
|
||||
|
||||
@ -60,7 +60,7 @@ Flash from Eclipse
|
||||
|
||||
You can integrate the "make flash" target into your Eclipse project to flash using esptool.py from the Eclipse UI:
|
||||
|
||||
* Right-click your project in Project Explorer (important to make sure you don't select a subdirectory of the project or Eclipse may find the wrong Makefile.)
|
||||
* Right-click your project in Project Explorer (important to make sure you select the project, not a directory in the project, or Eclipse may find the wrong Makefile.)
|
||||
|
||||
* Select Make Targets -> Create from the context menu.
|
||||
|
||||
@ -73,3 +73,8 @@ Note that you will need to use "make menuconfig" to set the serial port and othe
|
||||
Follow the same steps to add ``bootloader`` and ``partition_table`` targets, if necessary.
|
||||
|
||||
.. _eclipse.org: http://www.eclipse.org/
|
||||
|
||||
Eclipse Troubleshooting
|
||||
-----------------------
|
||||
|
||||
* ``*** Make was invoked from ... However please do not run make from the sdk or a component directory; ...`` - Eclipse will detect any directory with a Makefile in it as being a possible directory to run "make" in. All component directories also contain a Makefile (the wrong one), so it is important when using Project -> Make Target to always select the top-level project directory in Project Explorer.
|
||||
|
@ -49,6 +49,23 @@ summary := @echo
|
||||
details := @true
|
||||
endif
|
||||
|
||||
# Pseudo-target to handle the case where submodules need to be
|
||||
# re-initialised.
|
||||
#
|
||||
# $(eval $(call SubmoduleRequiredForFiles,FILENAMES)) to create a target that
|
||||
# automatically runs 'git submodule update --init' if those files
|
||||
# are missing, and fails if this is not possible.
|
||||
define SubmoduleRequiredForFiles
|
||||
$(1):
|
||||
@echo "WARNING: Missing submodule for $$@..."
|
||||
$(Q) [ -d ${IDF_PATH}/.git ] || ( echo "ERROR: esp-idf must be cloned from git to work."; exit 1)
|
||||
$(Q) [ -x $(which git) ] || ( echo "ERROR: Need to run 'git submodule --init' in esp-idf root directory."; exit 1)
|
||||
@echo "Attempting 'git submodule update --init' in esp-idf root directory..."
|
||||
cd ${IDF_PATH} && git submodule update --init
|
||||
endef
|
||||
|
||||
|
||||
|
||||
# General make utilities
|
||||
|
||||
# convenience variable for printing an 80 asterisk wide separator line
|
||||
|
@ -1,13 +1,13 @@
|
||||
#
|
||||
# Main Project Makefile
|
||||
# This Makefile is included directly from the user project Makefile in order to call the Makefiles of all the
|
||||
# components (in a separate make process) to build all the libraries, then links them together
|
||||
# into the final file. If so, PWD is the project dir (we assume).
|
||||
# This Makefile is included directly from the user project Makefile in order to call the component.mk
|
||||
# makefiles of all components (in a separate make process) to build all the libraries, then links them
|
||||
# together into the final file. If so, PWD is the project dir (we assume).
|
||||
#
|
||||
|
||||
#
|
||||
# This Makefile requires the environment variable IDF_PATH to be set to the directory where this
|
||||
# Makefile is located.
|
||||
# This makefile requires the environment variable IDF_PATH to be set to the top-level esp-idf directory
|
||||
# where this file is located.
|
||||
#
|
||||
|
||||
.PHONY: build-components menuconfig defconfig all build clean all_binaries
|
||||
@ -77,9 +77,9 @@ SRCDIRS ?= main
|
||||
COMPONENT_PATHS := $(foreach comp,$(COMPONENTS),$(firstword $(foreach dir,$(COMPONENT_DIRS),$(wildcard $(dir)/$(comp)))))
|
||||
COMPONENT_PATHS += $(abspath $(SRCDIRS))
|
||||
|
||||
#A component is buildable if it has a Makefile; we assume that a 'make -C $(component dir) build' results in a
|
||||
#lib$(componentname).a.
|
||||
COMPONENT_PATHS_BUILDABLE := $(foreach cp,$(COMPONENT_PATHS),$(if $(wildcard $(cp)/Makefile),$(cp)))
|
||||
#A component is buildable if it has a component.mk makefile; we assume that a
|
||||
# 'make -C $(component dir) -f component.mk build' results in a lib$(componentname).a
|
||||
COMPONENT_PATHS_BUILDABLE := $(foreach cp,$(COMPONENT_PATHS),$(if $(wildcard $(cp)/component.mk),$(cp)))
|
||||
|
||||
# Assemble global list of include dirs (COMPONENT_INCLUDES), and
|
||||
# LDFLAGS args (COMPONENT_LDFLAGS) supplied by each component.
|
||||
@ -98,7 +98,7 @@ COMPONENT_LDFLAGS :=
|
||||
#
|
||||
# Debugging this? Replace $(shell with $(error and you'll see the full command as-run.
|
||||
define GetVariable
|
||||
$(shell "$(MAKE)" -s --no-print-directory -C $(1) get_variable PROJECT_PATH=$(PROJECT_PATH) GET_VARIABLE=$(2) | sed -En "s/^$(2)=(.+)/\1/p" )
|
||||
$(shell "$(MAKE)" -s --no-print-directory -C $(1) -f component.mk get_variable PROJECT_PATH=$(PROJECT_PATH) GET_VARIABLE=$(2) | sed -En "s/^$(2)=(.+)/\1/p" )
|
||||
endef
|
||||
|
||||
COMPONENT_INCLUDES := $(abspath $(foreach comp,$(COMPONENT_PATHS_BUILDABLE),$(addprefix $(comp)/, \
|
||||
@ -193,7 +193,7 @@ define GenerateComponentPhonyTarget
|
||||
# $(2) - target to generate (build, clean)
|
||||
.PHONY: $(notdir $(1))-$(2)
|
||||
$(notdir $(1))-$(2): | $(BUILD_DIR_BASE)/$(notdir $(1))
|
||||
@+$(MAKE) -C $(BUILD_DIR_BASE)/$(notdir $(1)) -f $(1)/Makefile COMPONENT_BUILD_DIR=$(BUILD_DIR_BASE)/$(notdir $(1)) $(2)
|
||||
@+$(MAKE) -C $(BUILD_DIR_BASE)/$(notdir $(1)) -f $(1)/component.mk COMPONENT_BUILD_DIR=$(BUILD_DIR_BASE)/$(notdir $(1)) $(2)
|
||||
endef
|
||||
|
||||
define GenerateComponentTargets
|
||||
@ -206,7 +206,7 @@ $(BUILD_DIR_BASE)/$(notdir $(1)):
|
||||
# only invoked for the targets whose libraries appear in COMPONENT_LIBRARIES and hence the
|
||||
# APP_ELF dependencies.)
|
||||
$(BUILD_DIR_BASE)/$(notdir $(1))/lib$(notdir $(1)).a: $(notdir $(1))-build
|
||||
$(details) echo "$$^ responsible for $$@" # echo which build target built this file
|
||||
$(details) "Target '$$^' responsible for '$$@'" # echo which build target built this file
|
||||
endef
|
||||
|
||||
$(foreach component,$(COMPONENT_PATHS_BUILDABLE),$(eval $(call GenerateComponentTargets,$(component))))
|
||||
|
@ -26,9 +26,10 @@ function run_tests()
|
||||
print_status "Checking prerequisites"
|
||||
[ -z ${IDF_PATH} ] && echo "IDF_PATH is not set. Need path to esp-idf installation." && exit 2
|
||||
|
||||
print_status "Cloning template..."
|
||||
print_status "Cloning template from ${ESP_IDF_TEMPLATE_GIT}..."
|
||||
git clone ${ESP_IDF_TEMPLATE_GIT} template
|
||||
cd template
|
||||
git checkout ${CI_BUILD_REF_NAME} || echo "Using esp-idf-template default branch..."
|
||||
|
||||
print_status "Updating template config..."
|
||||
make defconfig || exit $?
|
||||
|
@ -5,5 +5,5 @@
|
||||
# process uses MinGW paths of the form /c/dir/dir/file. So parse these out...
|
||||
#
|
||||
# (regexp deliberate only matches after a space character to try and avoid false-positives.)
|
||||
echo "Running make in $(dirname $0)"
|
||||
echo "Running make in $(pwd)"
|
||||
make $@ V=1 | sed -E "s@ /([a-z])/(.+)/@ \1:/\2/@g" | sed -E "s@-I/([a-z])/(.+)/@-I\1:/\2/@g" | sed -E "s@-L/([a-z])/(.+)/@-L\1:/\2/@g"
|
Loading…
Reference in New Issue
Block a user