Merge branch 'master' into feature/freertos_static_buffers
* master: (117 commits) build system: Add -fno-rtti when compiling C++ code FreeRTOS KConfig: Limit tick rate to 1000Hz bootloader: Fix accidental tabs introduced in !78 build system: Print a WARNING if any submodule is out of date Fix stack overflow message format 'make flash' targets: Print serial port when flashing lwip/esp32: support iperf Add data memory for RMT peripheral syscall write: Should return number of bytes written Also push relevant tags over esp32: add libsmartconfig.a to link libs esp32: not link wps esp32/lib: update wifi lib to a1e5f8b9 esp32: remove esp_wps.h add smartconfig header files(merge this after updating libsmartconfig.a version v2.6.2) esp32/lib: update wifi lib to 3853d7ae Add Comments Modify spinlock error in periph_ctrl.c Define xcoreid offset, add warning in tcb struct wrt the need to also change that define when struct changes components/tcpip_adapter: add some comments ... # Conflicts: # components/freertos/queue.c # components/freertos/tasks.c
This commit is contained in:
commit
8ee1a05914
10
.gitignore
vendored
10
.gitignore
vendored
|
@ -7,8 +7,18 @@ GTAGS
|
|||
GRTAGS
|
||||
GPATH
|
||||
|
||||
# emacs
|
||||
.dir-locals.el
|
||||
|
||||
# emacs temp file suffixes
|
||||
*~
|
||||
.#*
|
||||
\#*#
|
||||
|
||||
# Example project files
|
||||
examples/*/sdkconfig
|
||||
examples/*/sdkconfig.old
|
||||
examples/*/build
|
||||
|
||||
# Bootloader files
|
||||
components/bootloader/src/sdkconfig.old
|
|
@ -64,10 +64,28 @@ build_ssc:
|
|||
script:
|
||||
- git clone ssh://git@gitlab.espressif.cn:27227/yinling/SSC.git
|
||||
- cd SSC
|
||||
- git checkout ${CI_BUILD_REF_NAME} || echo "Using SSC default branch..."
|
||||
- make defconfig
|
||||
- chmod +x gen_misc_ng.sh
|
||||
- ./gen_misc_ng.sh
|
||||
|
||||
build_examples:
|
||||
<<: *build_template
|
||||
artifacts:
|
||||
paths:
|
||||
- build_examples/*/*/build/*.bin
|
||||
- build_examples/*/*/build/*.elf
|
||||
- build_examples/*/*/build/*.map
|
||||
- build_examples/*/*/build/bootloader/*.bin
|
||||
expire_in: 6 mos
|
||||
|
||||
script:
|
||||
# it's not possible to build 100% out-of-tree and have the "artifacts"
|
||||
# mechanism work, but this is the next best thing
|
||||
- mkdir build_examples
|
||||
- cd build_examples
|
||||
- ${IDF_PATH}/make/build_examples.sh
|
||||
|
||||
test_nvs_on_host:
|
||||
stage: test
|
||||
image: espressif/esp32-ci-env
|
||||
|
@ -146,4 +164,4 @@ push_master_to_github:
|
|||
- chmod 600 ~/.ssh/id_rsa
|
||||
- echo -e "Host github.com\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config
|
||||
- git remote add github git@github.com:espressif/esp-idf.git
|
||||
- git push github HEAD:master
|
||||
- git push --follow-tags github HEAD:master
|
||||
|
|
3
.gitmodules
vendored
3
.gitmodules
vendored
|
@ -4,3 +4,6 @@
|
|||
[submodule "components/esptool_py/esptool"]
|
||||
path = components/esptool_py/esptool
|
||||
url = https://github.com/themadinventor/esptool.git
|
||||
[submodule "components/bt/lib"]
|
||||
path = components/bt/lib
|
||||
url = https://github.com/espressif/esp32-bt-lib.git
|
||||
|
|
37
CONTRIBUTING.md
Normal file
37
CONTRIBUTING.md
Normal file
|
@ -0,0 +1,37 @@
|
|||
# Contributions Guide
|
||||
|
||||
We welcome contributions to the esp-idf project!
|
||||
|
||||
## How to Contribute
|
||||
|
||||
Contributions to esp-idf - fixing bugs, adding features, adding documentation - are welcome. We accept contributions via [Github Pull Requests](https://help.github.com/articles/about-pull-requests/).
|
||||
|
||||
## Before Contributing
|
||||
|
||||
Before sending us a Pull Request, please consider this list of points:
|
||||
|
||||
* Is the contribution entirely your own work, or already licensed under an Apache License 2.0 compatible Open Source License? If not then we unfortunately cannot accept it.
|
||||
|
||||
* Does any new code conform to the esp-idf Style Guide? (Style Guide currently pending).
|
||||
|
||||
* Is the code adequately commented for people to understand how it is structured?
|
||||
|
||||
* Is there documentation or examples that go with code contributions? [There are additional suggestions for writing good examples in the examples README](examples/README.md).
|
||||
|
||||
* Are comments and documentation written in clear English, with no spelling or grammar errors?
|
||||
|
||||
* If the contribution contains multiple commits, are they grouped together into logical changes (one major change per pull request)? Are any commits with names like "fixed typo" [squashed into previous commits](http://eli.thegreenplace.net/2014/02/19/squashing-github-pull-requests-into-a-single-commit/)?
|
||||
|
||||
* If you're unsure about any of these points, please open the Pull Request anyhow and then ask us for feedback.
|
||||
|
||||
## Pull Request Process
|
||||
|
||||
After you open the Pull Request, there will probably be some discussion in the comments field of the request itself.
|
||||
|
||||
Once the Pull Request is ready to merge, it will first be merged into our internal git system for in-house automated testing.
|
||||
|
||||
If this process passes, it will be merged onto the public github repository.
|
||||
|
||||
## Legal Part
|
||||
|
||||
Before a contribution can be accepted, you will need to sign our [Contributor Agreement](docs/contributor-agreement.rst). You will be prompted for this automatically as part of the Pull Request process.
|
32
Kconfig
32
Kconfig
|
@ -19,38 +19,6 @@ config PYTHON
|
|||
help
|
||||
The executable name/path that is used to run python. On some systems Python 2.x
|
||||
may need to be invoked as python2.
|
||||
|
||||
config MEMMAP_BT
|
||||
bool "Reserve space for Bluetooth stack"
|
||||
default "n"
|
||||
help
|
||||
The Bluetooth stack uses memory that cannot be used as generic memory anymore. This
|
||||
reserves the space for that within the memory map of the compiled binary.
|
||||
|
||||
config MEMMAP_SMP
|
||||
bool "Reserve memory for two cores"
|
||||
default "y"
|
||||
help
|
||||
The ESP32 contains two cores. If you plan to only use one, you can disable this item
|
||||
to save some memory. (ToDo: Make this automatically depend on unicore support)
|
||||
|
||||
config MEMMAP_TRACEMEM
|
||||
bool "Use TRAX tracing feature"
|
||||
default "n"
|
||||
help
|
||||
The ESP32 contains a feature which allows you to trace the execution path the processor
|
||||
has taken through the program. This is stored in a chunk of 32K (16K for single-processor)
|
||||
of memory that can't be used for general purposes anymore. Disable this if you do not know
|
||||
what this is.
|
||||
|
||||
config MEMMAP_SPISRAM
|
||||
bool "Use external SPI SRAM chip as main memory"
|
||||
default "n"
|
||||
help
|
||||
The ESP32 can control an external SPI SRAM chip, adding the memory it contains to the
|
||||
main memory map. Enable this if you have this hardware and want to use it in the same
|
||||
way as on-chip RAM.
|
||||
|
||||
endmenu
|
||||
|
||||
source "$COMPONENT_KCONFIGS_PROJBUILD"
|
||||
|
|
18
README.md
18
README.md
|
@ -1,6 +1,18 @@
|
|||
# Using Espressif IoT Development Framework with the ESP32
|
||||
|
||||
# Prerequisites
|
||||
# Setting Up ESP-IDF
|
||||
|
||||
In the [docs](docs) directory you will find per-platform setup guides:
|
||||
|
||||
* [Windows Setup Guide](docs/windows-setup.rst)
|
||||
* [Mac OS Setup Guide](docs/macos-setup.rst)
|
||||
* [Linux Setup Guide](docs/linux-setup.rst)
|
||||
|
||||
# Finding A Project
|
||||
|
||||
As well as the [esp-idf-template](https://github.com/espressif/esp-idf-template) project mentioned in the setup guide, esp-idf comes with some example projects in the [examples](examples) directory.
|
||||
|
||||
Once you've found the project you want to work with, change to its directory and you can configure and build it:
|
||||
|
||||
# Configuring your project
|
||||
|
||||
|
@ -52,8 +64,10 @@ For more details about partition tables and how to create custom variations, vie
|
|||
|
||||
# Resources
|
||||
|
||||
* The [docs directory of the esp-idf repository](https://github.com/espressif/esp-idf/tree/master/docs) contains esp-idf documentation.
|
||||
* The [docs directory of the esp-idf repository](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.
|
||||
|
||||
* If you're interested in contributing to esp-idf, please check the [CONTRIBUTING.md](CONTRIBUTING.md) file.
|
||||
|
|
|
@ -30,6 +30,10 @@ extern "C"
|
|||
#define IROM_HIGH 0x40400000
|
||||
#define DROM_LOW 0x3F400000
|
||||
#define DROM_HIGH 0x3F800000
|
||||
#define RTC_IRAM_LOW 0x400C0000
|
||||
#define RTC_IRAM_HIGH 0x400C2000
|
||||
#define RTC_DATA_LOW 0x50000000
|
||||
#define RTC_DATA_HIGH 0x50002000
|
||||
|
||||
/*spi mode,saved in third byte in flash */
|
||||
enum {
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "rom/ets_sys.h"
|
||||
#include "rom/spi_flash.h"
|
||||
#include "rom/crc.h"
|
||||
#include "rom/rtc.h"
|
||||
|
||||
#include "soc/soc.h"
|
||||
#include "soc/cpu.h"
|
||||
|
@ -362,6 +363,10 @@ void unpack_load_app(const partition_pos_t* partition)
|
|||
uint32_t irom_load_addr = 0;
|
||||
uint32_t irom_size = 0;
|
||||
|
||||
/* Reload the RTC memory sections whenever a non-deepsleep reset
|
||||
is occuring */
|
||||
bool load_rtc_memory = rtc_get_reset_reason(0) != DEEPSLEEP_RESET;
|
||||
|
||||
ESP_LOGD(TAG, "bin_header: %u %u %u %u %08x", image_header.magic,
|
||||
image_header.blocks,
|
||||
image_header.spi_mode,
|
||||
|
@ -406,7 +411,18 @@ void unpack_load_app(const partition_pos_t* partition)
|
|||
map = true;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "section %d: paddr=0x%08x vaddr=0x%08x size=0x%05x (%6d) %s", section_index, pos, section_header.load_addr, section_header.data_len, section_header.data_len, (load)?"load":(map)?"map":"");
|
||||
if (!load_rtc_memory && address >= RTC_IRAM_LOW && address < RTC_IRAM_HIGH) {
|
||||
ESP_LOGD(TAG, "Skipping RTC code section at %08x\n", pos);
|
||||
load = false;
|
||||
}
|
||||
|
||||
if (!load_rtc_memory && address >= RTC_DATA_LOW && address < RTC_DATA_HIGH) {
|
||||
ESP_LOGD(TAG, "Skipping RTC data section at %08x\n", pos);
|
||||
load = false;
|
||||
}
|
||||
|
||||
ESP_LOGI(TAG, "section %d: paddr=0x%08x vaddr=0x%08x size=0x%05x (%6d) %s", section_index, pos,
|
||||
section_header.load_addr, section_header.data_len, section_header.data_len, (load)?"load":(map)?"map":"");
|
||||
|
||||
if (!load) {
|
||||
pos += section_header.data_len;
|
||||
|
|
|
@ -3,21 +3,27 @@ visible if MEMMAP_BT
|
|||
|
||||
|
||||
config BT_ENABLED
|
||||
bool "Enable low-level BT stack"
|
||||
depends on MEMMAP_BT
|
||||
bool
|
||||
depends on ESP32_ENABLE_STACK_BT
|
||||
help
|
||||
This compiles in the low-level BT stack.
|
||||
|
||||
config BT_BTLE
|
||||
bool "Enable BTLE"
|
||||
depends on BT_ENABLED
|
||||
help
|
||||
This compiles BTLE support
|
||||
|
||||
config BT_BT
|
||||
bool "Enable classic BT"
|
||||
depends on BT_ENABLED
|
||||
help
|
||||
This enables classic BT support
|
||||
#config BT_BTLE
|
||||
# bool "Enable BTLE"
|
||||
# depends on BT_ENABLED
|
||||
# help
|
||||
# This compiles BTLE support
|
||||
#
|
||||
#config BT_BT
|
||||
# bool "Enable classic BT"
|
||||
# depends on BT_ENABLED
|
||||
# help
|
||||
# This enables classic BT support
|
||||
|
||||
endmenu
|
||||
|
||||
# Memory reserved at start of DRAM for Bluetooth stack
|
||||
config BT_RESERVE_DRAM
|
||||
hex
|
||||
default 0x10000 if MEMMAP_BT
|
||||
default 0
|
||||
|
|
134
components/bt/bt.c
Normal file
134
components/bt/bt.c
Normal file
|
@ -0,0 +1,134 @@
|
|||
// 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 <stdio.h>
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/xtensa_api.h"
|
||||
#include "freertos/portmacro.h"
|
||||
#include "esp_types.h"
|
||||
#include "esp_system.h"
|
||||
#include "esp_task.h"
|
||||
#include "esp_intr.h"
|
||||
#include "esp_attr.h"
|
||||
#include "bt.h"
|
||||
|
||||
#if CONFIG_BT_ENABLED
|
||||
|
||||
/* not for user call, so don't put to include file */
|
||||
extern void btdm_osi_funcs_register(void *osi_funcs);
|
||||
extern void btdm_controller_init(void);
|
||||
|
||||
|
||||
#define BT_DEBUG(...)
|
||||
#define BT_API_CALL_CHECK(info, api_call, ret) \
|
||||
do{\
|
||||
esp_err_t __err = (api_call);\
|
||||
if ((ret) != __err) {\
|
||||
BT_DEBUG("%s %d %s ret=%d\n", __FUNCTION__, __LINE__, (info), __err);\
|
||||
return __err;\
|
||||
}\
|
||||
} while(0)
|
||||
|
||||
struct osi_funcs_t {
|
||||
xt_handler (*_set_isr)(int n, xt_handler f, void *arg);
|
||||
void (*_ints_on)(unsigned int mask);
|
||||
void (*_interrupt_disable)(void);
|
||||
void (*_interrupt_restore)(void);
|
||||
void (*_task_yield)(void);
|
||||
void *(*_semphr_create)(uint32_t max, uint32_t init);
|
||||
int32_t (*_semphr_give_from_isr)(void *semphr, void *hptw);
|
||||
int32_t (*_semphr_take)(void *semphr, uint32_t block_time_ms);
|
||||
void *(*_mutex_create)(void);
|
||||
int32_t (*_mutex_lock)(void *mutex);
|
||||
int32_t (*_mutex_unlock)(void *mutex);
|
||||
esp_err_t (* _read_efuse_mac)(uint8_t mac[6]);
|
||||
};
|
||||
|
||||
static portMUX_TYPE global_int_mux = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
static void IRAM_ATTR interrupt_disable(void)
|
||||
{
|
||||
portENTER_CRITICAL(&global_int_mux);
|
||||
}
|
||||
|
||||
static void IRAM_ATTR interrupt_restore(void)
|
||||
{
|
||||
portEXIT_CRITICAL(&global_int_mux);
|
||||
}
|
||||
|
||||
static void * IRAM_ATTR semphr_create_wrapper(uint32_t max, uint32_t init)
|
||||
{
|
||||
return (void *)xSemaphoreCreateCounting(max, init);
|
||||
}
|
||||
|
||||
static int32_t IRAM_ATTR semphr_give_from_isr_wrapper(void *semphr, void *hptw)
|
||||
{
|
||||
return (int32_t)xSemaphoreGiveFromISR(semphr, hptw);
|
||||
}
|
||||
|
||||
static int32_t IRAM_ATTR semphr_take_wrapper(void *semphr, uint32_t block_time_ms)
|
||||
{
|
||||
return (int32_t)xSemaphoreTake(semphr, block_time_ms / portTICK_RATE_MS);
|
||||
}
|
||||
|
||||
static void * IRAM_ATTR mutex_create_wrapper(void)
|
||||
{
|
||||
return (void *)xSemaphoreCreateMutex();
|
||||
}
|
||||
|
||||
static int32_t IRAM_ATTR mutex_lock_wrapper(void *mutex)
|
||||
{
|
||||
return (int32_t)xSemaphoreTake(mutex, portMAX_DELAY);
|
||||
}
|
||||
|
||||
static int32_t IRAM_ATTR mutex_unlock_wrapper(void *mutex)
|
||||
{
|
||||
return (int32_t)xSemaphoreGive(mutex);
|
||||
}
|
||||
|
||||
static struct osi_funcs_t osi_funcs = {
|
||||
._set_isr = xt_set_interrupt_handler,
|
||||
._ints_on = xt_ints_on,
|
||||
._interrupt_disable = interrupt_disable,
|
||||
._interrupt_restore = interrupt_restore,
|
||||
._task_yield = vPortYield,
|
||||
._semphr_create = semphr_create_wrapper,
|
||||
._semphr_give_from_isr = semphr_give_from_isr_wrapper,
|
||||
._semphr_take = semphr_take_wrapper,
|
||||
._mutex_create = mutex_create_wrapper,
|
||||
._mutex_lock = mutex_lock_wrapper,
|
||||
._mutex_unlock = mutex_unlock_wrapper,
|
||||
._read_efuse_mac = system_efuse_read_mac,
|
||||
};
|
||||
|
||||
static void bt_controller_task(void *pvParam)
|
||||
{
|
||||
btdm_osi_funcs_register(&osi_funcs);
|
||||
btdm_controller_init();
|
||||
}
|
||||
|
||||
void bt_controller_init()
|
||||
{
|
||||
xTaskCreatePinnedToCore(bt_controller_task, "btController",
|
||||
ESP_TASK_BT_CONTROLLER_STACK, NULL,
|
||||
ESP_TASK_BT_CONTROLLER_PRIO, NULL, 0);
|
||||
}
|
||||
|
||||
#endif
|
23
components/bt/component.mk
Normal file
23
components/bt/component.mk
Normal file
|
@ -0,0 +1,23 @@
|
|||
#
|
||||
# Component Makefile
|
||||
#
|
||||
|
||||
#COMPONENT_ADD_INCLUDEDIRS :=
|
||||
|
||||
COMPONENT_ADD_INCLUDEDIRS := include
|
||||
|
||||
CFLAGS += -Wno-error=unused-label -Wno-error=return-type -Wno-error=missing-braces -Wno-error=pointer-sign -Wno-error=parentheses
|
||||
|
||||
LIBS := btdm_app
|
||||
|
||||
COMPONENT_ADD_LDFLAGS := -lbt -L$(abspath lib) \
|
||||
$(addprefix -l,$(LIBS)) \
|
||||
$(LINKER_SCRIPTS)
|
||||
|
||||
include $(IDF_PATH)/make/component_common.mk
|
||||
|
||||
ALL_LIB_FILES := $(patsubst %,$(COMPONENT_PATH)/lib/lib%.a,$(LIBS))
|
||||
$(COMPONENT_LIBRARY): $(ALL_LIB_FILES)
|
||||
|
||||
# automatically trigger a git submodule update if BT library is missing
|
||||
$(eval $(call SubmoduleCheck,$(ALL_LIB_FILES),$(COMPONENT_PATH)/lib))
|
69
components/bt/include/bt.h
Normal file
69
components/bt/include/bt.h
Normal file
|
@ -0,0 +1,69 @@
|
|||
// 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 __BT_H__
|
||||
#define __BT_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @brief Initialize BT controller
|
||||
*
|
||||
* This function should be called only once, before any other BT functions are called.
|
||||
*/
|
||||
void bt_controller_init();
|
||||
|
||||
/** @brief: vhci_host_callback
|
||||
* used for vhci call host function to notify what host need to do
|
||||
*
|
||||
* notify_host_send_available: notify host can send packet to controller
|
||||
* notify_host_recv: notify host that controller has packet send to host
|
||||
*/
|
||||
typedef struct vhci_host_callback {
|
||||
|
||||
void (*notify_host_send_available)(void);
|
||||
int (*notify_host_recv)(uint8_t *data, uint16_t len);
|
||||
} vhci_host_callback_t;
|
||||
|
||||
/** @brief: API_vhci_host_check_send_available
|
||||
* used for check actively if the host can send packet to controller or not.
|
||||
* return true for ready to send, false means cannot send packet
|
||||
*/
|
||||
bool API_vhci_host_check_send_available(void);
|
||||
|
||||
/** @brief: API_vhci_host_send_packet
|
||||
* host send packet to controller
|
||||
* param data is the packet point, the param len is the packet length
|
||||
* return void
|
||||
*/
|
||||
void API_vhci_host_send_packet(uint8_t *data, uint16_t len);
|
||||
|
||||
/** @brief: API_vhci_host_register_callback
|
||||
* register the vhci referece callback, the call back
|
||||
* struct defined by vhci_host_callback structure.
|
||||
* param is the vhci_host_callback type variable
|
||||
*/
|
||||
void API_vhci_host_register_callback(const vhci_host_callback_t *callback);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __BT_H__ */
|
1
components/bt/lib
Submodule
1
components/bt/lib
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit bcbc35215c6d87279da4b87a74d3360c537d6724
|
14
components/driver/component.mk
Normal file
14
components/driver/component.mk
Normal file
|
@ -0,0 +1,14 @@
|
|||
#
|
||||
# Component Makefile
|
||||
#
|
||||
# This Makefile should, at the very least, just include $(SDK_PATH)/make/component.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 SDK documents if you need to do this.
|
||||
#
|
||||
|
||||
COMPONENT_ADD_INCLUDEDIRS := include
|
||||
|
||||
COMPONENT_PRIV_INCLUDEDIRS := include/driver
|
||||
|
||||
include $(IDF_PATH)/make/component_common.mk
|
368
components/driver/gpio.c
Normal file
368
components/driver/gpio.c
Normal file
|
@ -0,0 +1,368 @@
|
|||
// 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 <esp_types.h>
|
||||
#include "esp_err.h"
|
||||
#include "esp_intr.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/xtensa_api.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "soc/soc.h"
|
||||
|
||||
//TODO: move debug options to menuconfig
|
||||
#define GPIO_DBG_ENABLE (0)
|
||||
#define GPIO_WARNING_ENABLE (0)
|
||||
#define GPIO_ERROR_ENABLE (0)
|
||||
#define GPIO_INFO_ENABLE (0)
|
||||
//DBG INFOR
|
||||
#if GPIO_INFO_ENABLE
|
||||
#define GPIO_INFO ets_printf
|
||||
#else
|
||||
#define GPIO_INFO(...)
|
||||
#endif
|
||||
#if GPIO_WARNING_ENABLE
|
||||
#define GPIO_WARNING(format,...) do{\
|
||||
ets_printf("[waring][%s#%u]",__FUNCTION__,__LINE__);\
|
||||
ets_printf(format,##__VA_ARGS__);\
|
||||
}while(0)
|
||||
#else
|
||||
#define GPIO_WARNING(...)
|
||||
#endif
|
||||
#if GPIO_ERROR_ENABLE
|
||||
#define GPIO_ERROR(format,...) do{\
|
||||
ets_printf("[error][%s#%u]",__FUNCTION__,__LINE__);\
|
||||
ets_printf(format,##__VA_ARGS__);\
|
||||
}while(0)
|
||||
#else
|
||||
#define GPIO_ERROR(...)
|
||||
#endif
|
||||
|
||||
const uint32_t GPIO_PIN_MUX_REG[GPIO_PIN_COUNT] = {
|
||||
GPIO_PIN_REG_0,
|
||||
GPIO_PIN_REG_1,
|
||||
GPIO_PIN_REG_2,
|
||||
GPIO_PIN_REG_3,
|
||||
GPIO_PIN_REG_4,
|
||||
GPIO_PIN_REG_5,
|
||||
GPIO_PIN_REG_6,
|
||||
GPIO_PIN_REG_7,
|
||||
GPIO_PIN_REG_8,
|
||||
GPIO_PIN_REG_9,
|
||||
GPIO_PIN_REG_10,
|
||||
GPIO_PIN_REG_11,
|
||||
GPIO_PIN_REG_12,
|
||||
GPIO_PIN_REG_13,
|
||||
GPIO_PIN_REG_14,
|
||||
GPIO_PIN_REG_15,
|
||||
GPIO_PIN_REG_16,
|
||||
GPIO_PIN_REG_17,
|
||||
GPIO_PIN_REG_18,
|
||||
GPIO_PIN_REG_19,
|
||||
0,
|
||||
GPIO_PIN_REG_21,
|
||||
GPIO_PIN_REG_22,
|
||||
GPIO_PIN_REG_23,
|
||||
0,
|
||||
GPIO_PIN_REG_25,
|
||||
GPIO_PIN_REG_26,
|
||||
GPIO_PIN_REG_27,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
GPIO_PIN_REG_32,
|
||||
GPIO_PIN_REG_33,
|
||||
GPIO_PIN_REG_34,
|
||||
GPIO_PIN_REG_35,
|
||||
GPIO_PIN_REG_36,
|
||||
GPIO_PIN_REG_37,
|
||||
GPIO_PIN_REG_38,
|
||||
GPIO_PIN_REG_39
|
||||
};
|
||||
|
||||
static int is_valid_gpio(int gpio_num)
|
||||
{
|
||||
if(gpio_num >= GPIO_PIN_COUNT || GPIO_PIN_MUX_REG[gpio_num] == 0) {
|
||||
GPIO_ERROR("GPIO io_num=%d does not exist\n",gpio_num);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
esp_err_t gpio_set_intr_type(gpio_num_t gpio_num, gpio_int_type_t intr_type)
|
||||
{
|
||||
if(!is_valid_gpio(gpio_num)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if(intr_type >= GPIO_INTR_MAX) {
|
||||
GPIO_ERROR("Unknown GPIO intr:%u\n",intr_type);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
GPIO.pin[gpio_num].int_type = intr_type;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t gpio_intr_enable(gpio_num_t gpio_num)
|
||||
{
|
||||
if(!is_valid_gpio(gpio_num)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if(xPortGetCoreID() == 0) {
|
||||
GPIO.pin[gpio_num].int_ena = GPIO_PRO_CPU_INTR_ENA; //enable pro cpu intr
|
||||
} else {
|
||||
GPIO.pin[gpio_num].int_ena = GPIO_APP_CPU_INTR_ENA; //enable pro cpu intr
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t gpio_intr_disable(gpio_num_t gpio_num)
|
||||
{
|
||||
if(!is_valid_gpio(gpio_num)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
GPIO.pin[gpio_num].int_ena = 0; //disable GPIO intr
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t gpio_output_disable(gpio_num_t gpio_num)
|
||||
{
|
||||
if(!is_valid_gpio(gpio_num)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if(gpio_num < 32) {
|
||||
GPIO.enable_w1tc = (0x1 << gpio_num);
|
||||
} else {
|
||||
GPIO.enable1_w1tc.data = (0x1 << (gpio_num - 32));
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t gpio_output_enable(gpio_num_t gpio_num)
|
||||
{
|
||||
if(gpio_num >= 34) {
|
||||
GPIO_ERROR("io_num=%d can only be input\n",gpio_num);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if(!is_valid_gpio(gpio_num)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if(gpio_num < 32) {
|
||||
GPIO.enable_w1ts = (0x1 << gpio_num);
|
||||
} else {
|
||||
GPIO.enable1_w1ts.data = (0x1 << (gpio_num - 32));
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t gpio_set_level(gpio_num_t gpio_num, uint32_t level)
|
||||
{
|
||||
if(!GPIO_IS_VALID_GPIO(gpio_num)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if(level) {
|
||||
if(gpio_num < 32) {
|
||||
GPIO.out_w1ts = (1 << gpio_num);
|
||||
} else {
|
||||
GPIO.out1_w1ts.data = (1 << (gpio_num - 32));
|
||||
}
|
||||
} else {
|
||||
if(gpio_num < 32) {
|
||||
GPIO.out_w1tc = (1 << gpio_num);
|
||||
} else {
|
||||
GPIO.out1_w1tc.data = (1 << (gpio_num - 32));
|
||||
}
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
int gpio_get_level(gpio_num_t gpio_num)
|
||||
{
|
||||
if(gpio_num < 32) {
|
||||
return (GPIO.in >> gpio_num) & 0x1;
|
||||
} else {
|
||||
return (GPIO.in1.data >> (gpio_num - 32)) & 0x1;
|
||||
}
|
||||
}
|
||||
|
||||
esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull)
|
||||
{
|
||||
if(!is_valid_gpio(gpio_num)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
esp_err_t ret = ESP_OK;
|
||||
switch(pull) {
|
||||
case GPIO_PULLUP_ONLY:
|
||||
PIN_PULLUP_EN(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
PIN_PULLDWN_DIS(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
break;
|
||||
case GPIO_PULLDOWN_ONLY:
|
||||
PIN_PULLUP_DIS(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
PIN_PULLDWN_EN(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
break;
|
||||
case GPIO_PULLUP_PULLDOWN:
|
||||
PIN_PULLUP_EN(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
PIN_PULLDWN_EN(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
break;
|
||||
case GPIO_FLOATING:
|
||||
PIN_PULLUP_DIS(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
PIN_PULLDWN_DIS(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
break;
|
||||
default:
|
||||
GPIO_ERROR("Unknown pull up/down mode,gpio_num=%u,pull=%u\n",gpio_num,pull);
|
||||
ret = ESP_ERR_INVALID_ARG;
|
||||
break;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t gpio_set_direction(gpio_num_t gpio_num, gpio_mode_t mode)
|
||||
{
|
||||
if(!is_valid_gpio(gpio_num)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if(gpio_num >= 34 && (mode & (GPIO_MODE_DEF_OUTPUT))) {
|
||||
GPIO_ERROR("io_num=%d can only be input\n",gpio_num);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
esp_err_t ret = ESP_OK;
|
||||
if(mode & GPIO_MODE_DEF_INPUT) {
|
||||
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
} else {
|
||||
PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[gpio_num]);
|
||||
}
|
||||
if(mode & GPIO_MODE_DEF_OUTPUT) {
|
||||
if(gpio_num < 32) {
|
||||
GPIO.enable_w1ts = (0x1 << gpio_num);
|
||||
} else {
|
||||
GPIO.enable1_w1ts.data = (0x1 << (gpio_num - 32));
|
||||
}
|
||||
} else {
|
||||
if(gpio_num < 32) {
|
||||
GPIO.enable_w1tc = (0x1 << gpio_num);
|
||||
} else {
|
||||
GPIO.enable1_w1tc.data = (0x1 << (gpio_num - 32));
|
||||
}
|
||||
}
|
||||
if(mode & GPIO_MODE_DEF_OD) {
|
||||
GPIO.pin[gpio_num].pad_driver = 1;
|
||||
} else {
|
||||
GPIO.pin[gpio_num].pad_driver = 0;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t gpio_config(gpio_config_t *pGPIOConfig)
|
||||
{
|
||||
uint64_t gpio_pin_mask = (pGPIOConfig->pin_bit_mask);
|
||||
uint32_t io_reg = 0;
|
||||
uint32_t io_num = 0;
|
||||
uint64_t bit_valid = 0;
|
||||
if(pGPIOConfig->pin_bit_mask == 0 || pGPIOConfig->pin_bit_mask >= (((uint64_t) 1) << GPIO_PIN_COUNT)) {
|
||||
GPIO_ERROR("GPIO_PIN mask error \n");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if((pGPIOConfig->mode) & (GPIO_MODE_DEF_OUTPUT)) {
|
||||
//GPIO 34/35/36/37/38/39 can only be used as input mode;
|
||||
if((gpio_pin_mask & ( GPIO_SEL_34 | GPIO_SEL_35 | GPIO_SEL_36 | GPIO_SEL_37 | GPIO_SEL_38 | GPIO_SEL_39))) {
|
||||
GPIO_ERROR("GPIO34-39 can only be used as input mode\n");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
}
|
||||
do {
|
||||
io_reg = GPIO_PIN_MUX_REG[io_num];
|
||||
if(((gpio_pin_mask >> io_num) & BIT(0)) && io_reg) {
|
||||
GPIO_INFO("Gpio%02d |Mode:",io_num);
|
||||
if((pGPIOConfig->mode) & GPIO_MODE_DEF_INPUT) {
|
||||
GPIO_INFO("INPUT ");
|
||||
PIN_INPUT_ENABLE(GPIO_PIN_MUX_REG[io_num]);
|
||||
} else {
|
||||
PIN_INPUT_DISABLE(GPIO_PIN_MUX_REG[io_num]);
|
||||
}
|
||||
if((pGPIOConfig->mode) & GPIO_MODE_DEF_OD) {
|
||||
GPIO_INFO("OD ");
|
||||
GPIO.pin[io_num].pad_driver = 1; /*0x01 Open-drain */
|
||||
} else {
|
||||
GPIO.pin[io_num].pad_driver = 0; /*0x00 Normal gpio output */
|
||||
}
|
||||
if((pGPIOConfig->mode) & GPIO_MODE_DEF_OUTPUT) {
|
||||
GPIO_INFO("OUTPUT ");
|
||||
gpio_output_enable(io_num);
|
||||
} else {
|
||||
gpio_output_disable(io_num);
|
||||
}
|
||||
GPIO_INFO("|");
|
||||
if(pGPIOConfig->pull_up_en) {
|
||||
GPIO_INFO("PU ");
|
||||
PIN_PULLUP_EN(io_reg);
|
||||
} else {
|
||||
PIN_PULLUP_DIS(io_reg);
|
||||
}
|
||||
if(pGPIOConfig->pull_down_en) {
|
||||
GPIO_INFO("PD ");
|
||||
PIN_PULLDWN_EN(io_reg);
|
||||
} else {
|
||||
PIN_PULLDWN_DIS(io_reg);
|
||||
}
|
||||
GPIO_INFO("Intr:%d |\n",pGPIOConfig->intr_type);
|
||||
gpio_set_intr_type(io_num, pGPIOConfig->intr_type);
|
||||
if(pGPIOConfig->intr_type) {
|
||||
gpio_intr_enable(io_num);
|
||||
} else {
|
||||
gpio_intr_disable(io_num);
|
||||
}
|
||||
PIN_FUNC_SELECT(io_reg, PIN_FUNC_GPIO); /*function number 2 is GPIO_FUNC for each pin */
|
||||
} else if(bit_valid && (io_reg == 0)) {
|
||||
GPIO_WARNING("io_num=%d does not exist\n",io_num);
|
||||
}
|
||||
io_num++;
|
||||
} while(io_num < GPIO_PIN_COUNT);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t gpio_isr_register(uint32_t gpio_intr_num, void (*fn)(void*), void * arg)
|
||||
{
|
||||
if(fn == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
ESP_INTR_DISABLE(gpio_intr_num);
|
||||
intr_matrix_set(xPortGetCoreID(), ETS_GPIO_INTR_SOURCE, gpio_intr_num);
|
||||
xt_set_interrupt_handler(gpio_intr_num, fn, arg);
|
||||
ESP_INTR_ENABLE(gpio_intr_num);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
/*only level interrupt can be used for wake-up function*/
|
||||
esp_err_t gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type)
|
||||
{
|
||||
if(!is_valid_gpio(gpio_num)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
esp_err_t ret = ESP_OK;
|
||||
if((intr_type == GPIO_INTR_LOW_LEVEL) || (intr_type == GPIO_INTR_HIGH_LEVEL)) {
|
||||
GPIO.pin[gpio_num].int_type = intr_type;
|
||||
GPIO.pin[gpio_num].wakeup_enable = 0x1;
|
||||
} else {
|
||||
GPIO_ERROR("GPIO wakeup only support Level mode,but edge mode set. gpio_num:%u\n",gpio_num);
|
||||
ret = ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t gpio_wakeup_disable(gpio_num_t gpio_num)
|
||||
{
|
||||
if(!is_valid_gpio(gpio_num)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
GPIO.pin[gpio_num].wakeup_enable = 0;
|
||||
return ESP_OK;
|
||||
}
|
462
components/driver/include/driver/gpio.h
Normal file
462
components/driver/include/driver/gpio.h
Normal file
|
@ -0,0 +1,462 @@
|
|||
// 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 _DRIVER_GPIO_H_
|
||||
#define _DRIVER_GPIO_H_
|
||||
#include "esp_err.h"
|
||||
#include <esp_types.h>
|
||||
#include "soc/gpio_reg.h"
|
||||
#include "soc/gpio_struct.h"
|
||||
#include "soc/rtc_io_reg.h"
|
||||
#include "soc/io_mux_reg.h"
|
||||
#include "rom/gpio.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define GPIO_SEL_0 (BIT(0)) /* Pin 0 selected */
|
||||
#define GPIO_SEL_1 (BIT(1)) /* Pin 1 selected */
|
||||
#define GPIO_SEL_2 (BIT(2)) /* Pin 2 selected */
|
||||
#define GPIO_SEL_3 (BIT(3)) /* Pin 3 selected */
|
||||
#define GPIO_SEL_4 (BIT(4)) /* Pin 4 selected */
|
||||
#define GPIO_SEL_5 (BIT(5)) /* Pin 5 selected */
|
||||
#define GPIO_SEL_6 (BIT(6)) /* Pin 6 selected */
|
||||
#define GPIO_SEL_7 (BIT(7)) /* Pin 7 selected */
|
||||
#define GPIO_SEL_8 (BIT(8)) /* Pin 8 selected */
|
||||
#define GPIO_SEL_9 (BIT(9)) /* Pin 9 selected */
|
||||
#define GPIO_SEL_10 (BIT(10)) /* Pin 10 selected */
|
||||
#define GPIO_SEL_11 (BIT(11)) /* Pin 11 selected */
|
||||
#define GPIO_SEL_12 (BIT(12)) /* Pin 12 selected */
|
||||
#define GPIO_SEL_13 (BIT(13)) /* Pin 13 selected */
|
||||
#define GPIO_SEL_14 (BIT(14)) /* Pin 14 selected */
|
||||
#define GPIO_SEL_15 (BIT(15)) /* Pin 15 selected */
|
||||
#define GPIO_SEL_16 (BIT(16)) /* Pin 16 selected */
|
||||
#define GPIO_SEL_17 (BIT(17)) /* Pin 17 selected */
|
||||
#define GPIO_SEL_18 (BIT(18)) /* Pin 18 selected */
|
||||
#define GPIO_SEL_19 (BIT(19)) /* Pin 19 selected */
|
||||
|
||||
#define GPIO_SEL_21 (BIT(21)) /* Pin 21 selected */
|
||||
#define GPIO_SEL_22 (BIT(22)) /* Pin 22 selected */
|
||||
#define GPIO_SEL_23 (BIT(23)) /* Pin 23 selected */
|
||||
|
||||
#define GPIO_SEL_25 (BIT(25)) /* Pin 25 selected */
|
||||
#define GPIO_SEL_26 (BIT(26)) /* Pin 26 selected */
|
||||
#define GPIO_SEL_27 (BIT(27)) /* Pin 27 selected */
|
||||
|
||||
#define GPIO_SEL_32 ((uint64_t)(((uint64_t)1)<<32)) /* Pin 32 selected */
|
||||
#define GPIO_SEL_33 ((uint64_t)(((uint64_t)1)<<33)) /* Pin 33 selected */
|
||||
#define GPIO_SEL_34 ((uint64_t)(((uint64_t)1)<<34)) /* Pin 34 selected */
|
||||
#define GPIO_SEL_35 ((uint64_t)(((uint64_t)1)<<35)) /* Pin 35 selected */
|
||||
#define GPIO_SEL_36 ((uint64_t)(((uint64_t)1)<<36)) /* Pin 36 selected */
|
||||
#define GPIO_SEL_37 ((uint64_t)(((uint64_t)1)<<37)) /* Pin 37 selected */
|
||||
#define GPIO_SEL_38 ((uint64_t)(((uint64_t)1)<<38)) /* Pin 38 selected */
|
||||
#define GPIO_SEL_39 ((uint64_t)(((uint64_t)1)<<39)) /* Pin 39 selected */
|
||||
|
||||
#define GPIO_PIN_REG_0 PERIPHS_IO_MUX_GPIO0_U
|
||||
#define GPIO_PIN_REG_1 PERIPHS_IO_MUX_U0TXD_U
|
||||
#define GPIO_PIN_REG_2 PERIPHS_IO_MUX_GPIO2_U
|
||||
#define GPIO_PIN_REG_3 PERIPHS_IO_MUX_U0RXD_U
|
||||
#define GPIO_PIN_REG_4 PERIPHS_IO_MUX_GPIO4_U
|
||||
#define GPIO_PIN_REG_5 PERIPHS_IO_MUX_GPIO5_U
|
||||
#define GPIO_PIN_REG_6 PERIPHS_IO_MUX_SD_CLK_U
|
||||
#define GPIO_PIN_REG_7 PERIPHS_IO_MUX_SD_DATA0_U
|
||||
#define GPIO_PIN_REG_8 PERIPHS_IO_MUX_SD_DATA1_U
|
||||
#define GPIO_PIN_REG_9 PERIPHS_IO_MUX_SD_DATA2_U
|
||||
#define GPIO_PIN_REG_10 PERIPHS_IO_MUX_SD_DATA3_U
|
||||
#define GPIO_PIN_REG_11 PERIPHS_IO_MUX_SD_CMD_U
|
||||
#define GPIO_PIN_REG_12 PERIPHS_IO_MUX_MTDI_U
|
||||
#define GPIO_PIN_REG_13 PERIPHS_IO_MUX_MTCK_U
|
||||
#define GPIO_PIN_REG_14 PERIPHS_IO_MUX_MTMS_U
|
||||
#define GPIO_PIN_REG_15 PERIPHS_IO_MUX_MTDO_U
|
||||
#define GPIO_PIN_REG_16 PERIPHS_IO_MUX_GPIO16_U
|
||||
#define GPIO_PIN_REG_17 PERIPHS_IO_MUX_GPIO17_U
|
||||
#define GPIO_PIN_REG_18 PERIPHS_IO_MUX_GPIO18_U
|
||||
#define GPIO_PIN_REG_19 PERIPHS_IO_MUX_GPIO19_U
|
||||
#define GPIO_PIN_REG_20 PERIPHS_IO_MUX_GPIO20_U
|
||||
#define GPIO_PIN_REG_21 PERIPHS_IO_MUX_GPIO21_U
|
||||
#define GPIO_PIN_REG_22 PERIPHS_IO_MUX_GPIO22_U
|
||||
#define GPIO_PIN_REG_23 PERIPHS_IO_MUX_GPIO23_U
|
||||
#define GPIO_PIN_REG_25 PERIPHS_IO_MUX_GPIO25_U
|
||||
#define GPIO_PIN_REG_26 PERIPHS_IO_MUX_GPIO26_U
|
||||
#define GPIO_PIN_REG_27 PERIPHS_IO_MUX_GPIO27_U
|
||||
#define GPIO_PIN_REG_32 PERIPHS_IO_MUX_GPIO32_U
|
||||
#define GPIO_PIN_REG_33 PERIPHS_IO_MUX_GPIO33_U
|
||||
#define GPIO_PIN_REG_34 PERIPHS_IO_MUX_GPIO34_U
|
||||
#define GPIO_PIN_REG_35 PERIPHS_IO_MUX_GPIO35_U
|
||||
#define GPIO_PIN_REG_36 PERIPHS_IO_MUX_GPIO36_U
|
||||
#define GPIO_PIN_REG_37 PERIPHS_IO_MUX_GPIO37_U
|
||||
#define GPIO_PIN_REG_38 PERIPHS_IO_MUX_GPIO38_U
|
||||
#define GPIO_PIN_REG_39 PERIPHS_IO_MUX_GPIO39_U
|
||||
|
||||
#define GPIO_APP_CPU_INTR_ENA (BIT(0))
|
||||
#define GPIO_APP_CPU_NMI_INTR_ENA (BIT(1))
|
||||
#define GPIO_PRO_CPU_INTR_ENA (BIT(2))
|
||||
#define GPIO_PRO_CPU_NMI_INTR_ENA (BIT(3))
|
||||
#define GPIO_SDIO_EXT_INTR_ENA (BIT(4))
|
||||
|
||||
#define GPIO_MODE_DEF_INPUT (BIT0)
|
||||
#define GPIO_MODE_DEF_OUTPUT (BIT1)
|
||||
#define GPIO_MODE_DEF_OD (BIT2)
|
||||
|
||||
#define GPIO_PIN_COUNT 40
|
||||
extern const uint32_t GPIO_PIN_MUX_REG[GPIO_PIN_COUNT];
|
||||
#define GPIO_IS_VALID_GPIO(gpio_num) ((gpio_num < GPIO_PIN_COUNT && GPIO_PIN_MUX_REG[gpio_num] != 0)) //to decide whether it is a valid GPIO number
|
||||
#define GPIO_IS_VALID_OUTPUT_GPIO(gpio_num) ((GPIO_IS_VALID_GPIO(gpio_num)) && (gpio_num < 34)) //to decide whether it can be a valid GPIO number of output mode
|
||||
|
||||
typedef enum {
|
||||
GPIO_NUM_0 = 0,
|
||||
GPIO_NUM_1 = 1,
|
||||
GPIO_NUM_2 = 2,
|
||||
GPIO_NUM_3 = 3,
|
||||
GPIO_NUM_4 = 4,
|
||||
GPIO_NUM_5 = 5,
|
||||
GPIO_NUM_6 = 6,
|
||||
GPIO_NUM_7 = 7,
|
||||
GPIO_NUM_8 = 8,
|
||||
GPIO_NUM_9 = 9,
|
||||
GPIO_NUM_10 = 10,
|
||||
GPIO_NUM_11 = 11,
|
||||
GPIO_NUM_12 = 12,
|
||||
GPIO_NUM_13 = 13,
|
||||
GPIO_NUM_14 = 14,
|
||||
GPIO_NUM_15 = 15,
|
||||
GPIO_NUM_16 = 16,
|
||||
GPIO_NUM_17 = 17,
|
||||
GPIO_NUM_18 = 18,
|
||||
GPIO_NUM_19 = 19,
|
||||
|
||||
GPIO_NUM_21 = 21,
|
||||
GPIO_NUM_22 = 22,
|
||||
GPIO_NUM_23 = 23,
|
||||
|
||||
GPIO_NUM_25 = 25,
|
||||
GPIO_NUM_26 = 26,
|
||||
GPIO_NUM_27 = 27,
|
||||
|
||||
GPIO_NUM_32 = 32,
|
||||
GPIO_NUM_33 = 33,
|
||||
GPIO_NUM_34 = 34, /*input mode only */
|
||||
GPIO_NUM_35 = 35, /*input mode only */
|
||||
GPIO_NUM_36 = 36, /*input mode only */
|
||||
GPIO_NUM_37 = 37, /*input mode only */
|
||||
GPIO_NUM_38 = 38, /*input mode only */
|
||||
GPIO_NUM_39 = 39, /*input mode only */
|
||||
} gpio_num_t;
|
||||
|
||||
typedef enum {
|
||||
GPIO_INTR_DISABLE = 0, /* disable GPIO interrupt */
|
||||
GPIO_INTR_POSEDGE = 1, /* GPIO interrupt type : rising edge */
|
||||
GPIO_INTR_NEGEDGE = 2, /* GPIO interrupt type : falling edge */
|
||||
GPIO_INTR_ANYEDGE = 3, /* GPIO interrupt type : both rising and falling edge */
|
||||
GPIO_INTR_LOW_LEVEL = 4, /* GPIO interrupt type : input low level trigger */
|
||||
GPIO_INTR_HIGH_LEVEL = 5, /* GPIO interrupt type : input high level trigger */
|
||||
GPIO_INTR_MAX,
|
||||
} gpio_int_type_t;
|
||||
|
||||
typedef enum {
|
||||
GPIO_MODE_INPUT = GPIO_MODE_DEF_INPUT, /* GPIO mode : input only */
|
||||
GPIO_MODE_OUTPUT = GPIO_MODE_DEF_OUTPUT, /* GPIO mode : output only mode */
|
||||
GPIO_MODE_OUTPUT_OD = ((GPIO_MODE_DEF_OUTPUT)|(GPIO_MODE_DEF_OD)), /* GPIO mode : output only with open-drain mode */
|
||||
GPIO_MODE_INPUT_OUTPUT_OD = ((GPIO_MODE_DEF_INPUT)|(GPIO_MODE_DEF_OUTPUT)|(GPIO_MODE_DEF_OD)), /* GPIO mode : output and input with open-drain mode*/
|
||||
GPIO_MODE_INPUT_OUTPUT = ((GPIO_MODE_DEF_INPUT)|(GPIO_MODE_DEF_OUTPUT)), /* GPIO mode : output and input mode */
|
||||
} gpio_mode_t;
|
||||
|
||||
typedef enum {
|
||||
GPIO_PULLUP_DISABLE = 0x0, /* disable GPIO pull-up resistor */
|
||||
GPIO_PULLUP_ENABLE = 0x1, /* enable GPIO pull-up resistor */
|
||||
} gpio_pullup_t;
|
||||
|
||||
typedef enum {
|
||||
GPIO_PULLDOWN_DISABLE = 0x0, /* disable GPIO pull-down resistor */
|
||||
GPIO_PULLDOWN_ENABLE = 0x1, /* enable GPIO pull-down resistor */
|
||||
} gpio_pulldown_t;
|
||||
|
||||
typedef struct {
|
||||
uint64_t pin_bit_mask; /* GPIO pin: set with bit mask, each bit maps to a GPIO */
|
||||
gpio_mode_t mode; /* GPIO mode: set input/output mode */
|
||||
gpio_pullup_t pull_up_en; /* GPIO pull-up */
|
||||
gpio_pulldown_t pull_down_en; /* GPIO pull-down */
|
||||
gpio_int_type_t intr_type; /* GPIO interrupt type */
|
||||
} gpio_config_t;
|
||||
|
||||
typedef enum {
|
||||
GPIO_LOW_LEVEL = 0,
|
||||
GPIO_HIGH_LEVEL = 1,
|
||||
GPIO_LEVEL_ERR,
|
||||
} gpio_level_t;
|
||||
|
||||
typedef enum {
|
||||
GPIO_PULLUP_ONLY, /* Pad pull up */
|
||||
GPIO_PULLDOWN_ONLY, /* Pad pull down */
|
||||
GPIO_PULLUP_PULLDOWN, /* Pad pull up + pull down*/
|
||||
GPIO_FLOATING, /* Pad floating */
|
||||
} gpio_pull_mode_t;
|
||||
|
||||
typedef void (*gpio_event_callback)(gpio_num_t gpio_intr_num);
|
||||
|
||||
/** \defgroup Driver_APIs Driver APIs
|
||||
* @brief Driver APIs
|
||||
*/
|
||||
|
||||
/** @addtogroup Driver_APIs
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \defgroup GPIO_Driver_APIs GPIO Driver APIs
|
||||
* @brief GPIO APIs
|
||||
*/
|
||||
|
||||
/** @addtogroup GPIO_Driver_APIs
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief GPIO common configuration
|
||||
*
|
||||
* Use this Function ,Configure GPIO's Mode,pull-up,PullDown,IntrType
|
||||
*
|
||||
* @parameter[in] pGPIOConfig
|
||||
* pGPIOConfig.pin_bit_mask : Configure GPIO pins bits,set this parameter with bit mask.
|
||||
* If you want to configure GPIO34 and GPIO16, pin_bit_mask=GPIO_Pin_16|GPIO_Pin_34;
|
||||
* pGPIOConfig.mode : Configure GPIO mode,such as output ,input...
|
||||
* pGPIOConfig.pull_up_en : Enable or Disable pull-up
|
||||
* pGPIOConfig.pull_down_en : Enable or Disable pull-down
|
||||
* pGPIOConfig.intr_type : Configure GPIO interrupt trigger type
|
||||
* @return ESP_OK: success ;
|
||||
* ESP_ERR_INVALID_ARG: parameter error
|
||||
* ESP_FAIL : GPIO error
|
||||
*
|
||||
*/
|
||||
esp_err_t gpio_config(gpio_config_t *pGPIOConfig);
|
||||
|
||||
|
||||
/**
|
||||
* @brief GPIO set interrupt trigger type
|
||||
*
|
||||
* @parameter[in] gpio_num : GPIO number.
|
||||
* If you want to set output level of GPIO16, gpio_num should be GPIO_NUM_16 (16);
|
||||
* @parameter[in] intr_type: interrupt type, select from gpio_int_type_t
|
||||
*
|
||||
* @return ESP_OK : success
|
||||
* ESP_ERR_INVALID_ARG: parameter error
|
||||
*
|
||||
*/
|
||||
esp_err_t gpio_set_intr_type(gpio_num_t gpio_num, gpio_int_type_t intr_type);
|
||||
|
||||
/**
|
||||
* @brief enable GPIO module interrupt signal
|
||||
*
|
||||
* @parameter[in] gpio_num : GPIO number.
|
||||
* If you want to set output level of GPIO16, gpio_num should be GPIO_NUM_16 (16);
|
||||
*
|
||||
* @return ESP_OK : success
|
||||
* ESP_ERR_INVALID_ARG: parameter error
|
||||
*
|
||||
*/
|
||||
esp_err_t gpio_intr_enable(gpio_num_t gpio_num);
|
||||
|
||||
/**
|
||||
* @brief disable GPIO module interrupt signal
|
||||
*
|
||||
* @parameter[in] gpio_num : GPIO number.
|
||||
* If you want to set output level of GPIO16, gpio_num should be GPIO_NUM_16 (16);
|
||||
*
|
||||
* @return ESP_OK : success
|
||||
* ESP_ERR_INVALID_ARG: parameter error
|
||||
*
|
||||
*/
|
||||
esp_err_t gpio_intr_disable(gpio_num_t gpio_num);
|
||||
|
||||
/**
|
||||
* @brief GPIO set output level
|
||||
*
|
||||
* @parameter[in] gpio_num : GPIO number.
|
||||
* If you want to set output level of GPIO16, gpio_num should be GPIO_NUM_16 (16);
|
||||
* @parameter[in] level : Output level. 0: low ; 1: high
|
||||
*
|
||||
* @return ESP_OK : success
|
||||
* ESP_FAIL : GPIO error
|
||||
*
|
||||
*/
|
||||
esp_err_t gpio_set_level(gpio_num_t gpio_num, uint32_t level);
|
||||
|
||||
/**
|
||||
* @brief GPIO get input level
|
||||
*
|
||||
* @parameter[in] gpio_num : GPIO number.
|
||||
* If you want to get level of pin GPIO16, gpio_num should be GPIO_NUM_16 (16);
|
||||
*
|
||||
* @return 0 : the GPIO input level is 0
|
||||
* 1 : the GPIO input level is 1
|
||||
*
|
||||
*/
|
||||
int gpio_get_level(gpio_num_t gpio_num);
|
||||
|
||||
/**
|
||||
* @brief GPIO set direction
|
||||
*
|
||||
* Configure GPIO direction,such as output_only,input_only,output_and_input
|
||||
*
|
||||
* @parameter[in] gpio_num : Configure GPIO pins number,it should be GPIO number.
|
||||
* If you want to set direction of GPIO16, gpio_num should be GPIO_NUM_16 (16);
|
||||
* @parameter[in] mode : Configure GPIO direction,such as output_only,input_only,...
|
||||
*
|
||||
* @return ESP_OK : success
|
||||
* ESP_ERR_INVALID_ARG : fail
|
||||
* ESP_FAIL : GPIO error
|
||||
*
|
||||
*/
|
||||
esp_err_t gpio_set_direction(gpio_num_t gpio_num, gpio_mode_t mode);
|
||||
|
||||
/**
|
||||
* @brief GPIO set pull
|
||||
*
|
||||
* User this Function,configure GPIO pull mode,such as pull-up,pull-down
|
||||
*
|
||||
* @parameter[in] gpio_num : Configure GPIO pins number,it should be GPIO number.
|
||||
* If you want to set pull up or down mode for GPIO16,gpio_num should be GPIO_NUM_16 (16);
|
||||
* @parameter[in] pull : Configure GPIO pull up/down mode,such as pullup_only,pulldown_only,pullup_and_pulldown,...
|
||||
*
|
||||
* @return ESP_OK : success
|
||||
* ESP_ERR_INVALID_ARG : fail
|
||||
* ESP_FAIL : GPIO error
|
||||
*
|
||||
*/
|
||||
esp_err_t gpio_set_pull_mode(gpio_num_t gpio_num, gpio_pull_mode_t pull);
|
||||
|
||||
/**
|
||||
* @brief enable GPIO wake-up function.
|
||||
*
|
||||
* @param gpio_num_t gpio_num : GPIO number.
|
||||
*
|
||||
* @param gpio_int_type_t intr_type : only GPIO_INTR_LOLEVEL\GPIO_INTR_HILEVEL can be used
|
||||
*
|
||||
* @return ESP_OK: success
|
||||
* ESP_ERR_INVALID_ARG: parameter error
|
||||
*/
|
||||
esp_err_t gpio_wakeup_enable(gpio_num_t gpio_num, gpio_int_type_t intr_type);
|
||||
|
||||
/**
|
||||
* @brief disable GPIO wake-up function.
|
||||
*
|
||||
* @param gpio_num_t gpio_num: GPIO number
|
||||
*
|
||||
* @return ESP_OK: success
|
||||
* ESP_ERR_INVALID_ARG: parameter error
|
||||
*/
|
||||
esp_err_t gpio_wakeup_disable(gpio_num_t gpio_num);
|
||||
|
||||
/**
|
||||
* @brief register GPIO interrupt handler, the handler is an ISR.
|
||||
* The handler will be attached to the same CPU core that this function is running on.
|
||||
* Users should know that which CPU is running and then pick a INUM that is not used by system.
|
||||
* We can find the information of INUM and interrupt level in soc.h.
|
||||
* TODO: to move INUM options to menu_config
|
||||
* @parameter uint32_t gpio_intr_num : GPIO interrupt number,check the info in soc.h, and please see the core-isa.h for more details
|
||||
* @parameter void (* fn)(void* ) : interrupt handler function.
|
||||
* Note that the handler function MUST be defined with attribution of "IRAM_ATTR".
|
||||
* @parameter void * arg : parameter for handler function
|
||||
*
|
||||
* @return ESP_OK : success ;
|
||||
* ESP_FAIL: gpio error
|
||||
*/
|
||||
esp_err_t gpio_isr_register(uint32_t gpio_intr_num, void (*fn)(void*), void * arg);
|
||||
|
||||
/**
|
||||
* *************** ATTENTION ********************/
|
||||
/**
|
||||
*
|
||||
* Each GPIO has its own separate configuration register, so we do not use
|
||||
* a lock to serialize access to them. This works under the assumption that
|
||||
* no situation will occur where two tasks try to configure the same GPIO
|
||||
* pin simultaneously. It is up to the application developer to guarantee this.
|
||||
*/
|
||||
|
||||
|
||||
/*----------EXAMPLE TO CONIFGURE GPIO AS OUTPUT ------------ */
|
||||
/* gpio_config_t io_conf;
|
||||
* io_conf.intr_type = GPIO_INTR_DISABLE; //disable interrupt
|
||||
* io_conf.mode = GPIO_MODE_OUTPUT; //set as output mode
|
||||
* io_conf.pin_bit_mask = GPIO_SEL_18 | GPIO_SEL_19; //bit mask of the pins that you want to set,e.g.GPIO18/19
|
||||
* io_conf.pull_down_en = 0; //disable pull-down mode
|
||||
* io_conf.pull_up_en = 0; //disable pull-up mode
|
||||
* gpio_config(&io_conf); //configure GPIO with the given settings
|
||||
**/
|
||||
/*----------EXAMPLE TO CONIFGURE GPIO AS OUTPUT ------------ */
|
||||
/* io_conf.intr_type = GPIO_INTR_POSEDGE; //set posedge interrupt
|
||||
* io_conf.mode = GPIO_MODE_INPUT; //set as input
|
||||
* io_conf.pin_bit_mask = GPIO_SEL_4 | GPIO_SEL_5; //bit mask of the pins that you want to set, e.g.,GPIO4/5
|
||||
* io_conf.pull_down_en = 0; //disable pull-down mode
|
||||
* io_conf.pull_up_en = 1; //enable pull-up mode
|
||||
* gpio_config(&io_conf); //configure GPIO with the given settings
|
||||
*----------EXAMPLE TO SET ISR HANDLER ----------------------*/
|
||||
/* gpio_isr_register(18,gpio_intr_test,NULL); //hook the isr handler for GPIO interrupt
|
||||
* //the first parameter is INUM, you can pick one form interrupt level 1/2 which is not used by the system.
|
||||
* //NOTE1:user should arrange the INUMs that used, better not to use a same INUM for different interrupt.
|
||||
* //NOTE2:do not pick the INUM that already occupied by the system.
|
||||
* //NOTE3:refer to soc.h to check which INUMs that can be used.
|
||||
*-------------EXAMPLE OF HANDLER FUNCTION-------------------*/
|
||||
/*#include "esp_attr.h"
|
||||
* void IRAM_ATTR gpio_intr_test(void* arg)
|
||||
*{
|
||||
* //GPIO intr process
|
||||
* ets_printf("in gpio_intr\n");
|
||||
* uint32_t gpio_num = 0;
|
||||
* uint32_t gpio_intr_status = READ_PERI_REG(GPIO_STATUS_REG); //read status to get interrupt status for GPIO0-31
|
||||
* uint32_t gpio_intr_status_h = READ_PERI_REG(GPIO_STATUS1_REG);//read status1 to get interrupt status for GPIO32-39
|
||||
* SET_PERI_REG_MASK(GPIO_STATUS_W1TC_REG, gpio_intr_status); //Clear intr for gpio0-gpio31
|
||||
* SET_PERI_REG_MASK(GPIO_STATUS1_W1TC_REG, gpio_intr_status_h); //Clear intr for gpio32-39
|
||||
* do {
|
||||
* if(gpio_num < 32) {
|
||||
* if(gpio_intr_status & BIT(gpio_num)) { //gpio0-gpio31
|
||||
* ets_printf("Intr GPIO%d ,val: %d\n",gpio_num,gpio_get_level(gpio_num));
|
||||
* //This is an isr handler, you should post an event to process it in RTOS queue.
|
||||
* }
|
||||
* } else {
|
||||
* if(gpio_intr_status_h & BIT(gpio_num - 32)) {
|
||||
* ets_printf("Intr GPIO%d, val : %d\n",gpio_num,gpio_get_level(gpio_num));
|
||||
* //This is an isr handler, you should post an event to process it in RTOS queue.
|
||||
* }
|
||||
* }
|
||||
* } while(++gpio_num < GPIO_PIN_COUNT);
|
||||
*}
|
||||
*----EXAMPLE OF I2C CONFIG AND PICK SIGNAL FOR IO MATRIX---*/
|
||||
/* gpio_config_t io_conf;
|
||||
* io_conf.intr_type = GPIO_INTR_DISABLE; //disable interrupt
|
||||
* io_conf.mode = GPIO_MODE_INPUT_OUTPUT_OD; //set as output mode
|
||||
* io_conf.pin_bit_mask = GPIO_SEL_21 | GPIO_SEL_22; //bit mask of the pins that you want to set,e.g.GPIO21/22
|
||||
* io_conf.pull_down_en = 0; //disable pull-down mode
|
||||
* io_conf.pull_up_en = 1; //enable pull-up mode
|
||||
* gpio_config(&io_conf); //configure GPIO with the given settings
|
||||
* gpio_matrix_out(21, EXT_I2C_SCL_O_IDX, 0, 0); //set output signal for io_matrix
|
||||
* gpio_matrix_out(22, EXT_I2C_SDA_O_IDX, 0, 0); //set output signal for io_matrix
|
||||
* gpio_matrix_in( 22, EXT_I2C_SDA_I_IDX, 0); //set input signal for io_matrix
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _DRIVER_GPIO_H_ */
|
406
components/driver/include/driver/ledc.h
Normal file
406
components/driver/include/driver/ledc.h
Normal file
|
@ -0,0 +1,406 @@
|
|||
// 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 _DRIVER_LEDC_H_
|
||||
#define _DRIVER_LEDC_H_
|
||||
#include "esp_err.h"
|
||||
#include "soc/soc.h"
|
||||
#include "soc/ledc_reg.h"
|
||||
#include "soc/ledc_reg.h"
|
||||
#include "soc/ledc_struct.h"
|
||||
#include "driver/gpio.h"
|
||||
#include "driver/periph_ctrl.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define LEDC_APB_CLK_HZ (APB_CLK_FREQ)
|
||||
#define LEDC_REF_CLK_HZ (1*1000000)
|
||||
|
||||
typedef enum {
|
||||
LEDC_HIGH_SPEED_MODE = 0, /*LEDC high speed speed_mode */
|
||||
//in this version, we only support high speed speed_mode. We will access low speed speed_mode later
|
||||
//LEDC_LOW_SPEED_MODE, /*LEDC low speed speed_mode */
|
||||
LEDC_SPEED_MODE_MAX,
|
||||
} ledc_mode_t;
|
||||
|
||||
typedef enum {
|
||||
LEDC_INTR_DISABLE = 0, /*Disable LEDC interrupt */
|
||||
LEDC_INTR_FADE_END, /*Enable LEDC interrupt */
|
||||
} ledc_intr_type_t;
|
||||
|
||||
typedef enum {
|
||||
LEDC_DUTY_DIR_DECREASE = 0, /*LEDC duty decrease direction */
|
||||
LEDC_DUTY_DIR_INCREASE = 1, /*LEDC duty increase direction */
|
||||
} ledc_duty_direction_t;
|
||||
|
||||
typedef enum {
|
||||
LEDC_REF_TICK = 0, /*LEDC timer clock divided from reference tick(1Mhz) */
|
||||
LEDC_APB_CLK, /*LEDC timer clock divided from APB clock(80Mhz)*/
|
||||
} ledc_clk_src_t;
|
||||
|
||||
typedef enum {
|
||||
LEDC_TIMER_0 = 0, /*LEDC source timer TIMER0 */
|
||||
LEDC_TIMER_1, /*LEDC source timer TIMER1 */
|
||||
LEDC_TIMER_2, /*LEDC source timer TIMER2 */
|
||||
LEDC_TIMER_3, /*LEDC source timer TIMER3 */
|
||||
} ledc_timer_t;
|
||||
|
||||
typedef enum {
|
||||
LEDC_CHANNEL_0 = 0, /*LEDC channel 0 */
|
||||
LEDC_CHANNEL_1, /*LEDC channel 1 */
|
||||
LEDC_CHANNEL_2, /*LEDC channel 2 */
|
||||
LEDC_CHANNEL_3, /*LEDC channel 3 */
|
||||
LEDC_CHANNEL_4, /*LEDC channel 4 */
|
||||
LEDC_CHANNEL_5, /*LEDC channel 5 */
|
||||
LEDC_CHANNEL_6, /*LEDC channel 6 */
|
||||
LEDC_CHANNEL_7, /*LEDC channel 7 */
|
||||
} ledc_channel_t;
|
||||
|
||||
typedef enum {
|
||||
LEDC_TIMER_10_BIT = 10, /*LEDC PWM depth 10Bit */
|
||||
LEDC_TIMER_11_BIT = 11, /*LEDC PWM depth 11Bit */
|
||||
LEDC_TIMER_12_BIT = 12, /*LEDC PWM depth 12Bit */
|
||||
LEDC_TIMER_13_BIT = 13, /*LEDC PWM depth 13Bit */
|
||||
LEDC_TIMER_14_BIT = 14, /*LEDC PWM depth 14Bit */
|
||||
LEDC_TIMER_15_BIT = 15, /*LEDC PWM depth 15Bit */
|
||||
} ledc_timer_bit_t;
|
||||
|
||||
typedef struct {
|
||||
int gpio_num; /*the LEDC output gpio_num, if you want to use gpio16, gpio_num = 16*/
|
||||
ledc_mode_t speed_mode; /*LEDC speed speed_mode, high-speed mode or low-speed mode*/
|
||||
ledc_channel_t channel; /*LEDC channel(0 - 7)*/
|
||||
ledc_intr_type_t intr_type; /*configure interrupt, Fade interrupt enable or Fade interrupt disable*/
|
||||
ledc_timer_t timer_sel; /*Select the timer source of channel (0 - 3)*/
|
||||
uint32_t duty; /*LEDC channel duty, the duty range is [0, (2**bit_num) - 1], */
|
||||
} ledc_channel_config_t;
|
||||
|
||||
typedef struct {
|
||||
ledc_mode_t speed_mode; /*LEDC speed speed_mode, high-speed mode or low-speed mode*/
|
||||
ledc_timer_bit_t bit_num; /*LEDC channel duty depth*/
|
||||
ledc_timer_t timer_num; /*The timer source of channel (0 - 3)*/
|
||||
uint32_t freq_hz; /*LEDC timer frequency(Hz)*/
|
||||
} ledc_timer_config_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief LEDC channel configuration
|
||||
*
|
||||
* User this Function, configure LEDC channel with the given channel/output gpio_num/interrupt/source timer/frequency(Hz)/LEDC depth
|
||||
*
|
||||
* @param[in] ledc_channel_config_t
|
||||
* ledc_channel_config_t.speed_mode : LEDC speed speed_mode
|
||||
* ledc_channel_config_t.gpio_num : LEDC output gpio_num, if you want to use gpio16, ledc_channel_config_t.gpio_num = 16
|
||||
* ledc_channel_config_t.channel : LEDC channel(0 - 7)
|
||||
* ledc_channel_config_t.intr_type : configure interrupt, Fade interrupt enable or Fade interrupt disable
|
||||
* ledc_channel_config_t.timer_sel : Select the timer source of channel (0 - 3), high speed channel must bind with high speed timer.
|
||||
* ledc_channel_config_t.duty : LEDC channel duty, the duty range is [0, (2**timer_bit_num) - 1],
|
||||
* @return ESP_OK: success
|
||||
* ESP_ERR_INVALID_ARG: parameter error
|
||||
*
|
||||
*/
|
||||
esp_err_t ledc_channel_config(ledc_channel_config_t* ledc_conf);
|
||||
|
||||
/**
|
||||
* @brief LEDC timer configuration
|
||||
*
|
||||
* User this Function, configure LEDC timer with the given source timer/frequency(Hz)/bit_num
|
||||
*
|
||||
* @param[in] ledc_timer_config_t
|
||||
* ledc_timer_config_t.speed_mode : LEDC speed speed_mode
|
||||
* ledc_timer_config_t.timer_num : Select the timer source of channel (0 - 3)
|
||||
* ledc_timer_config_t.freq_hz : LEDC channel frequency(Hz),
|
||||
* ledc_timer_config_t.bit_num : LEDC channel duty depth
|
||||
* @return ESP_OK: success
|
||||
* ESP_ERR_INVALID_ARG: parameter error
|
||||
* ESP_FAIL: Can not find a proper pre-divider number base on the given frequency and the current bit_num.
|
||||
*
|
||||
*/
|
||||
esp_err_t ledc_timer_config(ledc_timer_config_t* timer_conf);
|
||||
|
||||
/**
|
||||
* @brief LEDC update channel parameters
|
||||
*
|
||||
* Call this function to activate the LEDC updated parameters.
|
||||
* After ledc_set_duty, ledc_set_fade, we need to call this function to update the settings.
|
||||
*
|
||||
* @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
|
||||
*
|
||||
* @param[in] channel : LEDC channel(0-7), select from ledc_channel_t
|
||||
*
|
||||
* @return ESP_OK: success
|
||||
* ESP_ERR_INVALID_ARG: parameter error
|
||||
*
|
||||
*/
|
||||
esp_err_t ledc_update_duty(ledc_mode_t speed_mode, ledc_channel_t channel);
|
||||
|
||||
/**
|
||||
* @brief LEDC stop
|
||||
*
|
||||
* Disable LEDC output, and set idle level
|
||||
*
|
||||
* @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
|
||||
*
|
||||
* @param[in] channel : LEDC channel(0-7), select from ledc_channel_t
|
||||
*
|
||||
* @return ESP_OK: success
|
||||
* ESP_ERR_INVALID_ARG: parameter error
|
||||
*/
|
||||
esp_err_t ledc_stop(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t idle_level);
|
||||
|
||||
/**
|
||||
* @brief LEDC set channel frequency(Hz)
|
||||
*
|
||||
* Set LEDC frequency(Hz)
|
||||
*
|
||||
* @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
|
||||
*
|
||||
* @param[in] timer_num : LEDC timer index(0-3), select from ledc_timer_t
|
||||
*
|
||||
* @param[in] freq_hz : set the LEDC frequency
|
||||
*
|
||||
* @return ESP_OK: success
|
||||
* ESP_ERR_INVALID_ARG: parameter error
|
||||
* ESP_FAIL: Can not find a proper pre-divider number base on the given frequency and the current bit_num.
|
||||
*/
|
||||
esp_err_t ledc_set_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num, uint32_t freq_hz);
|
||||
|
||||
/**
|
||||
* @brief LEDC get channel frequency(Hz)
|
||||
*
|
||||
* @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
|
||||
*
|
||||
* @param[in] timer_num : LEDC timer index(0-3), select from ledc_timer_t
|
||||
*
|
||||
* @return 0 : error
|
||||
* others : current LEDC frequency
|
||||
*
|
||||
*/
|
||||
uint32_t ledc_get_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num);
|
||||
|
||||
/**
|
||||
* @brief LEDC set duty
|
||||
*
|
||||
* Set LEDC duty, After the function calls the ledc_update_duty function, the function can take effect.
|
||||
*
|
||||
* @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
|
||||
*
|
||||
* @param[in] channel : LEDC channel(0-7), select from ledc_channel_t
|
||||
*
|
||||
* @param[in] duty : set the LEDC duty, the duty range is [0, (2**bit_num) - 1]
|
||||
*
|
||||
* @return ESP_OK: success
|
||||
* ESP_ERR_INVALID_ARG: parameter error
|
||||
*/
|
||||
esp_err_t ledc_set_duty(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t duty);
|
||||
|
||||
/**
|
||||
* @brief LEDC get duty
|
||||
*
|
||||
* @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
|
||||
*
|
||||
* @param[in] channel : LEDC channel(0-7), select from ledc_channel_t
|
||||
*
|
||||
*
|
||||
* @return -1: parameter error
|
||||
* other value: current LEDC duty
|
||||
*
|
||||
*/
|
||||
int ledc_get_duty(ledc_mode_t speed_mode, ledc_channel_t channel);
|
||||
|
||||
/**
|
||||
* @brief LEDC set gradient
|
||||
*
|
||||
* Set LEDC gradient, After the function calls the ledc_update_duty function, the function can take effect.
|
||||
*
|
||||
* @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
|
||||
*
|
||||
* @param[in] channel : LEDC channel(0-7), select from ledc_channel_t
|
||||
*
|
||||
* @param[in] duty : set the start of the gradient duty, the duty range is [0, (2**bit_num) - 1]
|
||||
*
|
||||
* @param[in] gradule_direction : set the direction of the gradient
|
||||
*
|
||||
* @param[in] step_num : set the number of the gradient
|
||||
*
|
||||
* @param[in] duty_cyle_num : set how many LEDC tick each time the gradient lasts
|
||||
*
|
||||
* @param[in] duty_scale : set gradient change amplitude
|
||||
*
|
||||
* @return ESP_OK : success
|
||||
* ESP_ERR_INVALID_ARG : parameter error
|
||||
*/
|
||||
esp_err_t ledc_set_fade(ledc_mode_t speed_mode, uint32_t channel, uint32_t duty, ledc_duty_direction_t gradule_direction,
|
||||
uint32_t step_num, uint32_t duty_cyle_num, uint32_t duty_scale);
|
||||
|
||||
/**
|
||||
* @brief register LEDC interrupt handler, the handler is an ISR.
|
||||
* The handler will be attached to the same CPU core that this function is running on.
|
||||
* Users should know that which CPU is running and then pick a INUM that is not used by system.
|
||||
* We can find the information of INUM and interrupt level in soc.h.
|
||||
* TODO: to move INUM options to menu_config
|
||||
* @param[in] uint32_t ledc_intr_num : LEDC interrupt number, check the info in soc.h, and please see the core-isa.h for more details
|
||||
* @param[in] void (* fn)(void* ) : interrupt handler function.
|
||||
* Note that the handler function MUST be defined with attribution of "IRAM_ATTR".
|
||||
* @param[in] void * arg : parameter for handler function
|
||||
*
|
||||
* @return ESP_OK : success ;
|
||||
* ESP_ERR_INVALID_ARG : function ptr error.
|
||||
*/
|
||||
esp_err_t ledc_isr_register(uint32_t ledc_intr_num, void (*fn)(void*), void * arg);
|
||||
|
||||
/**
|
||||
* @brief configure LEDC settings
|
||||
*
|
||||
* @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
|
||||
*
|
||||
* @param[in] timer_sel : timer index(0-3), there are 4 timers in LEDC module
|
||||
*
|
||||
* @param[in] div_num : timer clock divide number, the timer clock is divided from the selected clock source
|
||||
*
|
||||
* @param[in] bit_num : the count number of one period, counter range is 0 ~ ((2 ** bit_num) - 1)
|
||||
*
|
||||
* @param[in] clk_src : select LEDC source clock.
|
||||
*
|
||||
* @return -1: parameter error
|
||||
* other value: current LEDC duty
|
||||
*
|
||||
*/
|
||||
esp_err_t ledc_timer_set(ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t div_num, uint32_t bit_num, ledc_clk_src_t clk_src);
|
||||
|
||||
/**
|
||||
* @brief reset LEDC timer
|
||||
*
|
||||
* @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
|
||||
*
|
||||
* @param[in] timer_sel : LEDC timer index(0-3), select from ledc_timer_t
|
||||
*
|
||||
*
|
||||
* @return ESP_ERR_INVALID_ARG: parameter error
|
||||
* ESP_OK: success
|
||||
*
|
||||
*/
|
||||
esp_err_t ledc_timer_rst(ledc_mode_t speed_mode, uint32_t timer_sel);
|
||||
|
||||
/**
|
||||
* @brief pause LEDC timer counter
|
||||
*
|
||||
* @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
|
||||
*
|
||||
* @param[in] timer_sel : LEDC timer index(0-3), select from ledc_timer_t
|
||||
*
|
||||
*
|
||||
* @return ESP_ERR_INVALID_ARG: parameter error
|
||||
* ESP_OK: success
|
||||
*
|
||||
*/
|
||||
esp_err_t ledc_timer_pause(ledc_mode_t speed_mode, uint32_t timer_sel);
|
||||
|
||||
/**
|
||||
* @brief pause LEDC timer resume
|
||||
*
|
||||
* @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
|
||||
*
|
||||
* @param[in] timer_sel : LEDC timer index(0-3), select from ledc_timer_t
|
||||
*
|
||||
*
|
||||
* @return ESP_ERR_INVALID_ARG: parameter error
|
||||
* ESP_OK: success
|
||||
*
|
||||
*/
|
||||
esp_err_t ledc_timer_resume(ledc_mode_t speed_mode, uint32_t timer_sel);
|
||||
|
||||
/**
|
||||
* @brief bind LEDC channel with the selected timer
|
||||
*
|
||||
* @param[in] speed_mode : select the LEDC speed_mode, high-speed mode and low-speed mode, now we only support high-speed mode. We will access low-speed mode in next version
|
||||
*
|
||||
* @param[in] channel : LEDC channel index(0-7), select from ledc_channel_t
|
||||
*
|
||||
* @param[in] timer_idx : LEDC timer index(0-3), select from ledc_timer_t
|
||||
*
|
||||
*
|
||||
* @return ESP_ERR_INVALID_ARG: parameter error
|
||||
* ESP_OK: success
|
||||
*
|
||||
*/
|
||||
esp_err_t ledc_bind_channel_timer(ledc_mode_t speed_mode, uint32_t channel, uint32_t timer_idx);
|
||||
|
||||
/***************************EXAMPLE**********************************
|
||||
*
|
||||
*
|
||||
* ----------------EXAMPLE OF LEDC SETTING ---------------------
|
||||
* //1. enable LEDC
|
||||
* periph_module_enable(PERIPH_LEDC_MODULE); //enable LEDC module, or you can not set any register of it.
|
||||
*
|
||||
* //2. set LEDC timer
|
||||
* ledc_timer_config_t timer_conf = {
|
||||
* .bit_num = LEDC_TIMER_12_BIT, //set timer counter bit number
|
||||
* .freq_hz = 1000, //set frequency of pwm, here, 1000Hz
|
||||
* .speed_mode = LEDC_HIGH_SPEED_MODE //timer mode,
|
||||
* .timer_num = LEDC_TIMER_0, //timer number
|
||||
* };
|
||||
* ledc_timer_config(&timer_conf); //setup timer.
|
||||
*
|
||||
* //3. set LEDC channel
|
||||
* ledc_channel_config_t ledc_conf = {
|
||||
* .channel = LEDC_CHANNEL_0; //set LEDC channel 0
|
||||
* .duty = 1000; //set the duty for initialization.(duty range is 0 ~ ((2**bit_num)-1)
|
||||
* .gpio_num = 16; //GPIO number
|
||||
* .intr_type = LEDC_INTR_FADE_END; //GPIO INTR TYPE, as an example, we enable fade_end interrupt here.
|
||||
* .speed_mode = LEDC_HIGH_SPEED_MODE; //set LEDC mode, from ledc_mode_t
|
||||
* .timer_sel = LEDC_TIMER_0; //set LEDC timer source, if different channel use one timer, the frequency and bit_num of these channels should be the same
|
||||
* }
|
||||
* ledc_channel_config(&ledc_conf); //setup the configuration
|
||||
*
|
||||
* ----------------EXAMPLE OF SETTING DUTY --- -----------------
|
||||
* uint32_t ledc_channel = LEDC_CHANNEL_0; //LEDC channel(0-73)
|
||||
* uint32_t duty = 2000; //duty range is 0 ~ ((2**bit_num)-1)
|
||||
* LEDC_set_duty(LEDC_HIGH_SPEED_MODE, ledc_channel, duty); //set speed mode, channel, and duty.
|
||||
* ledc_update_duty(LEDC_HIGH_SPEED_MODE, ledc_channel); //after set duty, we need to call ledc_update_duty to update the settings.
|
||||
*
|
||||
*
|
||||
* ----------------EXAMPLE OF LEDC INTERRUPT ------------------
|
||||
* //we have fade_end interrupt and counter overflow interrupt. we just give an example of fade_end interrupt here.
|
||||
* ledc_isr_register(18, ledc_isr_handler, NULL); //hook the isr handler for LEDC interrupt
|
||||
* //the first parameter is INUM, you can pick one form interrupt level 1/2 which is not used by the system.
|
||||
* //NOTE1:user should arrange the INUMs that used, better not to use a same INUM for different interrupt source.
|
||||
* //NOTE2:do not pick the INUM that already occupied by the system.
|
||||
* //NOTE3:refer to soc.h to check which INUMs that can be used.
|
||||
* ----------------EXAMPLE OF INTERRUPT HANDLER ---------------
|
||||
* #include "esp_attr.h"
|
||||
* void IRAM_ATTR ledc_isr_handler(void* arg) //we should add 'IRAM_ATTR' attribution when we declare the isr function
|
||||
* {
|
||||
* uint32_t intr_st = LEDC.int_st.val; //read LEDC interrupt status.
|
||||
*
|
||||
* //you will find which channels have triggered fade_end interrupt here,
|
||||
* //then, you can post some event to RTOS queue to process the event.
|
||||
* //later we will add a queue in the driver code.
|
||||
*
|
||||
* LEDC.int_clr.val = intr_st; //clear LEDC interrupt status.
|
||||
* }
|
||||
*
|
||||
*
|
||||
*--------------------------END OF EXAMPLE --------------------------
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _DRIVER_LEDC_H_ */
|
70
components/driver/include/driver/periph_ctrl.h
Normal file
70
components/driver/include/driver/periph_ctrl.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
// 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 _DRIVER_PERIPH_CTRL_H_
|
||||
#define _DRIVER_PERIPH_CTRL_H_
|
||||
#include "esp_err.h"
|
||||
#include "soc/soc.h"
|
||||
#include "soc/dport_reg.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
PERIPH_LEDC_MODULE = 0,
|
||||
PERIPH_UART0_MODULE,
|
||||
PERIPH_UART1_MODULE,
|
||||
PERIPH_UART2_MODULE,
|
||||
PERIPH_I2C0_MODULE,
|
||||
PERIPH_I2C1_MODULE,
|
||||
PERIPH_I2S0_MODULE,
|
||||
PERIPH_I2S1_MODULE,
|
||||
PERIPH_TIMG0_MODULE,
|
||||
PERIPH_TIMG1_MODULE,
|
||||
PERIPH_PWM0_MODULE,
|
||||
PERIPH_PWM1_MODULE,
|
||||
PERIPH_PWM2_MODULE,
|
||||
PERIPH_PWM3_MODULE,
|
||||
PERIPH_UHCI0_MODULE,
|
||||
PERIPH_UHCI1_MODULE,
|
||||
} periph_module_t;
|
||||
|
||||
/**
|
||||
* @brief enable peripheral module
|
||||
*
|
||||
* @param[in] periph : Peripheral module name
|
||||
*
|
||||
*
|
||||
* @return NULL
|
||||
*
|
||||
*/
|
||||
void periph_module_enable(periph_module_t periph);
|
||||
|
||||
/**
|
||||
* @brief disable peripheral module
|
||||
*
|
||||
* @param[in] periph : Peripheral module name
|
||||
*
|
||||
*
|
||||
* @return NULL
|
||||
*
|
||||
*/
|
||||
void periph_module_disable(periph_module_t periph);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _DRIVER_PERIPH_CTRL_H_ */
|
432
components/driver/ledc.c
Normal file
432
components/driver/ledc.c
Normal file
|
@ -0,0 +1,432 @@
|
|||
// 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 <esp_types.h>
|
||||
#include "esp_intr.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/xtensa_api.h"
|
||||
#include "soc/gpio_sig_map.h"
|
||||
#include "driver/ledc.h"
|
||||
|
||||
//TODO: to use APIs in esp_log.h.
|
||||
#define LEDC_DBG_WARING_ENABLE (0)
|
||||
#define LEDC_DBG_ERROR_ENABLE (0)
|
||||
#define LEDC_INFO_ENABLE (0)
|
||||
#define LEDC_DBG_ENABLE (0)
|
||||
|
||||
//DBG INFOR
|
||||
#if LEDC_DBG_ENABLE
|
||||
#define LEDC_DBG(format,...) do{\
|
||||
ets_printf("[dbg][%s#%u]",__FUNCTION__,__LINE__);\
|
||||
ets_printf(format,##__VA_ARGS__);\
|
||||
}while(0)
|
||||
#else
|
||||
#define LEDC_DBG(...)
|
||||
#endif
|
||||
|
||||
#if LEDC_INFO_ENABLE
|
||||
#define LEDC_INFO(format,...) do{\
|
||||
ets_printf("[info][%s#%u]",__FUNCTION__,__LINE__);\
|
||||
ets_printf(format,##__VA_ARGS__);\
|
||||
}while(0)
|
||||
#else
|
||||
#define LEDC_INFO(...)
|
||||
#endif
|
||||
|
||||
#if LEDC_DBG_WARING_ENABLE
|
||||
#define LEDC_WARING(format,...) do{\
|
||||
ets_printf("[waring][%s#%u]",__FUNCTION__,__LINE__);\
|
||||
ets_printf(format,##__VA_ARGS__);\
|
||||
}while(0)
|
||||
#else
|
||||
#define LEDC_WARING(...)
|
||||
#endif
|
||||
#if LEDC_DBG_ERROR_ENABLE
|
||||
#define LEDC_ERROR(format,...) do{\
|
||||
ets_printf("[error][%s#%u]",__FUNCTION__,__LINE__);\
|
||||
ets_printf(format,##__VA_ARGS__);\
|
||||
}while(0)
|
||||
#else
|
||||
#define LEDC_ERROR(...)
|
||||
#endif
|
||||
|
||||
static portMUX_TYPE ledc_spinlock = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
static bool ledc_is_valid_channel(uint32_t channel)
|
||||
{
|
||||
if(channel > LEDC_CHANNEL_7) {
|
||||
LEDC_ERROR("LEDC CHANNEL ERR: %d\n",channel);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ledc_is_valid_mode(uint32_t mode)
|
||||
{
|
||||
if(mode >= LEDC_SPEED_MODE_MAX) {
|
||||
LEDC_ERROR("LEDC MODE ERR: %d\n",mode);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool ledc_is_valid_timer(int timer)
|
||||
{
|
||||
if(timer > LEDC_TIMER_3) {
|
||||
LEDC_ERROR("LEDC TIMER ERR: %d\n", timer);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
esp_err_t ledc_timer_set(ledc_mode_t speed_mode, ledc_timer_t timer_sel, uint32_t div_num, uint32_t bit_num, ledc_clk_src_t clk_src)
|
||||
{
|
||||
if(!ledc_is_valid_mode(speed_mode)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if(!ledc_is_valid_timer(timer_sel)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
portENTER_CRITICAL(&ledc_spinlock);
|
||||
LEDC.timer_group[speed_mode].timer[timer_sel].conf.div_num = div_num;
|
||||
LEDC.timer_group[speed_mode].timer[timer_sel].conf.tick_sel = clk_src;
|
||||
LEDC.timer_group[speed_mode].timer[timer_sel].conf.bit_num = bit_num;
|
||||
if(speed_mode != LEDC_HIGH_SPEED_MODE) {
|
||||
LEDC.timer_group[speed_mode].timer[timer_sel].conf.low_speed_update = 1;
|
||||
}
|
||||
portEXIT_CRITICAL(&ledc_spinlock);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t ledc_duty_config(ledc_mode_t speed_mode, uint32_t channel_num, uint32_t hpoint_val, uint32_t duty_val,
|
||||
uint32_t duty_direction, uint32_t duty_num, uint32_t duty_cycle, uint32_t duty_scale)
|
||||
{
|
||||
portENTER_CRITICAL(&ledc_spinlock);
|
||||
LEDC.channel_group[speed_mode].channel[channel_num].hpoint.hpoint = hpoint_val;
|
||||
LEDC.channel_group[speed_mode].channel[channel_num].duty.duty = duty_val;
|
||||
LEDC.channel_group[speed_mode].channel[channel_num].conf1.val = ((duty_direction & LEDC_DUTY_INC_HSCH0_V) << LEDC_DUTY_INC_HSCH0_S) |
|
||||
((duty_num & LEDC_DUTY_NUM_HSCH0_V) << LEDC_DUTY_NUM_HSCH0_S) |
|
||||
((duty_cycle & LEDC_DUTY_CYCLE_HSCH0_V) << LEDC_DUTY_CYCLE_HSCH0_S) |
|
||||
((duty_scale & LEDC_DUTY_SCALE_HSCH0_V) << LEDC_DUTY_SCALE_HSCH0_S);
|
||||
portEXIT_CRITICAL(&ledc_spinlock);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t ledc_bind_channel_timer(ledc_mode_t speed_mode, uint32_t channel, uint32_t timer_idx)
|
||||
{
|
||||
if(!ledc_is_valid_mode(speed_mode)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if(!ledc_is_valid_timer(timer_idx)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
portENTER_CRITICAL(&ledc_spinlock);
|
||||
LEDC.channel_group[speed_mode].channel[channel].conf0.timer_sel = timer_idx;
|
||||
portEXIT_CRITICAL(&ledc_spinlock);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t ledc_timer_rst(ledc_mode_t speed_mode, uint32_t timer_sel)
|
||||
{
|
||||
if(!ledc_is_valid_mode(speed_mode)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if(!ledc_is_valid_timer(timer_sel)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
portENTER_CRITICAL(&ledc_spinlock);
|
||||
LEDC.timer_group[speed_mode].timer[timer_sel].conf.rst = 1;
|
||||
LEDC.timer_group[speed_mode].timer[timer_sel].conf.rst = 0;
|
||||
portEXIT_CRITICAL(&ledc_spinlock);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t ledc_timer_pause(ledc_mode_t speed_mode, uint32_t timer_sel)
|
||||
{
|
||||
if(!ledc_is_valid_mode(speed_mode)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if(!ledc_is_valid_timer(timer_sel)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
portENTER_CRITICAL(&ledc_spinlock);
|
||||
LEDC.timer_group[speed_mode].timer[timer_sel].conf.pause = 1;
|
||||
portEXIT_CRITICAL(&ledc_spinlock);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t ledc_timer_resume(ledc_mode_t speed_mode, uint32_t timer_sel)
|
||||
{
|
||||
if(!ledc_is_valid_mode(speed_mode)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if(!ledc_is_valid_timer(timer_sel)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
portENTER_CRITICAL(&ledc_spinlock);
|
||||
LEDC.timer_group[speed_mode].timer[timer_sel].conf.pause = 0;
|
||||
portEXIT_CRITICAL(&ledc_spinlock);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t ledc_enable_intr_type(ledc_mode_t speed_mode, uint32_t channel, ledc_intr_type_t type)
|
||||
{
|
||||
if(!ledc_is_valid_mode(speed_mode)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
uint32_t value;
|
||||
uint32_t intr_type = type;
|
||||
portENTER_CRITICAL(&ledc_spinlock);
|
||||
value = LEDC.int_ena.val;
|
||||
if(intr_type == LEDC_INTR_FADE_END) {
|
||||
LEDC.int_ena.val = value | BIT(LEDC_DUTY_CHNG_END_HSCH0_INT_ENA_S + channel);
|
||||
} else {
|
||||
LEDC.int_ena.val = (value & (~(BIT(LEDC_DUTY_CHNG_END_HSCH0_INT_ENA_S + channel))));
|
||||
}
|
||||
portEXIT_CRITICAL(&ledc_spinlock);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t ledc_isr_register(uint32_t ledc_intr_num, void (*fn)(void*), void * arg)
|
||||
{
|
||||
if(fn == NULL) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
portENTER_CRITICAL(&ledc_spinlock);
|
||||
ESP_INTR_DISABLE(ledc_intr_num);
|
||||
intr_matrix_set(xPortGetCoreID(), ETS_LEDC_INTR_SOURCE, ledc_intr_num);
|
||||
xt_set_interrupt_handler(ledc_intr_num, fn, arg);
|
||||
ESP_INTR_ENABLE(ledc_intr_num);
|
||||
portEXIT_CRITICAL(&ledc_spinlock);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t ledc_timer_config(ledc_timer_config_t* timer_conf)
|
||||
{
|
||||
int freq_hz = timer_conf->freq_hz;
|
||||
int bit_num = timer_conf->bit_num;
|
||||
int timer_num = timer_conf->timer_num;
|
||||
int speed_mode = timer_conf->speed_mode;
|
||||
|
||||
if(!ledc_is_valid_mode(speed_mode)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if(freq_hz == 0 || bit_num == 0 || bit_num > LEDC_TIMER_15_BIT) {
|
||||
LEDC_ERROR("freq_hz=%u bit_num=%u\n", freq_hz, bit_num);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if(timer_num > LEDC_TIMER_3) {
|
||||
LEDC_ERROR("Time Select %u\n", timer_num);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
esp_err_t ret = ESP_OK;
|
||||
uint32_t precision = (0x1 << bit_num); //2**depth
|
||||
uint64_t div_param = ((uint64_t) LEDC_APB_CLK_HZ << 8) / freq_hz / precision; //8bit fragment
|
||||
int timer_clk_src;
|
||||
/*Fail ,because the div_num overflow or too small*/
|
||||
if(div_param <= 256 || div_param > LEDC_DIV_NUM_HSTIMER0_V) { //REF TICK
|
||||
/*Selet the reference tick*/
|
||||
div_param = ((uint64_t) LEDC_REF_CLK_HZ << 8) / freq_hz / precision;
|
||||
if(div_param <= 256 || div_param > LEDC_DIV_NUM_HSTIMER0_V) {
|
||||
LEDC_ERROR("div param err,div_param=%u\n", div_param);
|
||||
ret = ESP_FAIL;
|
||||
}
|
||||
timer_clk_src = LEDC_REF_TICK;
|
||||
} else { //APB TICK
|
||||
timer_clk_src = LEDC_APB_CLK;
|
||||
}
|
||||
/*set timer parameters*/
|
||||
/*timer settings decide the clk of counter and the period of PWM*/
|
||||
ledc_timer_set(speed_mode, timer_num, div_param, bit_num, timer_clk_src);
|
||||
/* reset timer.*/
|
||||
ledc_timer_rst(speed_mode, timer_num);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t ledc_channel_config(ledc_channel_config_t* ledc_conf)
|
||||
{
|
||||
uint32_t speed_mode = ledc_conf->speed_mode;
|
||||
uint32_t gpio_num = ledc_conf->gpio_num;
|
||||
uint32_t ledc_channel = ledc_conf->channel;
|
||||
uint32_t timer_select = ledc_conf->timer_sel;
|
||||
uint32_t intr_type = ledc_conf->intr_type;
|
||||
uint32_t duty = ledc_conf->duty;
|
||||
|
||||
if(!ledc_is_valid_channel(ledc_channel)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if(!ledc_is_valid_mode(speed_mode)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if(!GPIO_IS_VALID_OUTPUT_GPIO(gpio_num)) {
|
||||
LEDC_ERROR("GPIO number error: IO%d\n ", gpio_num);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if(timer_select > LEDC_TIMER_3) {
|
||||
LEDC_ERROR("Time Select %u\n", timer_select);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
esp_err_t ret = ESP_OK;
|
||||
/*set channel parameters*/
|
||||
/* channel parameters decide how the waveform looks like in one period*/
|
||||
/* set channel duty, duty range is (0 ~ ((2 ** bit_num) - 1))*/
|
||||
ledc_set_duty(speed_mode, ledc_channel, duty);
|
||||
/*update duty settings*/
|
||||
ledc_update_duty(speed_mode, ledc_channel);
|
||||
/*bind the channel with the timer*/
|
||||
ledc_bind_channel_timer(speed_mode, ledc_channel, timer_select);
|
||||
/*set interrupt type*/
|
||||
ledc_enable_intr_type(speed_mode, ledc_channel, intr_type);
|
||||
LEDC_INFO("LEDC_PWM CHANNEL %1u|GPIO %02u|Duty %04u|Time %01u\n",
|
||||
ledc_channel, gpio_num, duty, timer_select
|
||||
);
|
||||
/*set LEDC signal in gpio matrix*/
|
||||
PIN_FUNC_SELECT(GPIO_PIN_MUX_REG[gpio_num], PIN_FUNC_GPIO);
|
||||
gpio_set_direction(gpio_num, GPIO_MODE_OUTPUT);
|
||||
gpio_matrix_out(gpio_num, LEDC_HS_SIG_OUT0_IDX + ledc_channel, 0, 0);
|
||||
return ret;
|
||||
}
|
||||
|
||||
esp_err_t ledc_update_duty(ledc_mode_t speed_mode, ledc_channel_t channel)
|
||||
{
|
||||
if(!ledc_is_valid_mode(speed_mode)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if(!ledc_is_valid_channel(channel)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
portENTER_CRITICAL(&ledc_spinlock);
|
||||
LEDC.channel_group[speed_mode].channel[channel].conf0.sig_out_en = 1;
|
||||
LEDC.channel_group[speed_mode].channel[channel].conf1.duty_start = 1;
|
||||
portEXIT_CRITICAL(&ledc_spinlock);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t ledc_stop(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t idle_level)
|
||||
{
|
||||
if(!ledc_is_valid_mode(speed_mode)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if(!ledc_is_valid_channel(channel)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
portENTER_CRITICAL(&ledc_spinlock);
|
||||
LEDC.channel_group[speed_mode].channel[channel].conf0.idle_lv = idle_level & 0x1;
|
||||
LEDC.channel_group[speed_mode].channel[channel].conf0.sig_out_en = 0;
|
||||
LEDC.channel_group[speed_mode].channel[channel].conf1.duty_start = 0;
|
||||
portEXIT_CRITICAL(&ledc_spinlock);
|
||||
return ESP_OK;
|
||||
}
|
||||
esp_err_t ledc_set_fade(ledc_mode_t speed_mode, uint32_t channel, uint32_t duty, ledc_duty_direction_t fade_direction,
|
||||
uint32_t step_num, uint32_t duty_cyle_num, uint32_t duty_scale)
|
||||
{
|
||||
if(!ledc_is_valid_mode(speed_mode)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if(!ledc_is_valid_channel(channel)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if(fade_direction > LEDC_DUTY_DIR_INCREASE) {
|
||||
LEDC_ERROR("Duty direction err\n");
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if(step_num > LEDC_DUTY_NUM_HSCH0_V || duty_cyle_num > LEDC_DUTY_CYCLE_HSCH0_V || duty_scale > LEDC_DUTY_SCALE_HSCH0_V) {
|
||||
LEDC_ERROR("step_num=%u duty_cyle_num=%u duty_scale=%u\n", step_num, duty_cyle_num, duty_scale);
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
ledc_duty_config(speed_mode,
|
||||
channel, //uint32_t chan_num,
|
||||
0, //uint32_t hpoint_val,
|
||||
duty << 4, //uint32_t duty_val,the least 4 bits are decimal part
|
||||
fade_direction, //uint32_t increase,
|
||||
step_num, //uint32_t duty_num,
|
||||
duty_cyle_num, //uint32_t duty_cycle,
|
||||
duty_scale //uint32_t duty_scale
|
||||
);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
esp_err_t ledc_set_duty(ledc_mode_t speed_mode, ledc_channel_t channel, uint32_t duty)
|
||||
{
|
||||
if(!ledc_is_valid_mode(speed_mode)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
if(!ledc_is_valid_channel(channel)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
ledc_duty_config(speed_mode,
|
||||
channel, //uint32_t chan_num,
|
||||
0, //uint32_t hpoint_val,
|
||||
duty << 4, //uint32_t duty_val,the least 4 bits are decimal part
|
||||
1, //uint32_t increase,
|
||||
1, //uint32_t duty_num,
|
||||
1, //uint32_t duty_cycle,
|
||||
0 //uint32_t duty_scale
|
||||
);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
int ledc_get_duty(ledc_mode_t speed_mode, ledc_channel_t channel)
|
||||
{
|
||||
if(!ledc_is_valid_mode(speed_mode)) {
|
||||
return -1;
|
||||
}
|
||||
uint32_t duty = (LEDC.channel_group[speed_mode].channel[channel].duty_rd.duty_read >> 4);
|
||||
return duty;
|
||||
}
|
||||
|
||||
esp_err_t ledc_set_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num, uint32_t freq_hz)
|
||||
{
|
||||
if(!ledc_is_valid_mode(speed_mode)) {
|
||||
return ESP_ERR_INVALID_ARG;
|
||||
}
|
||||
portENTER_CRITICAL(&ledc_spinlock);
|
||||
esp_err_t ret = ESP_OK;
|
||||
uint32_t div_num = 0;
|
||||
uint32_t bit_num = LEDC.timer_group[speed_mode].timer[timer_num].conf.bit_num;
|
||||
uint32_t timer_source_clk = LEDC.timer_group[speed_mode].timer[timer_num].conf.tick_sel;
|
||||
uint32_t precision = (0x1 << bit_num);
|
||||
if(timer_source_clk == LEDC_APB_CLK) {
|
||||
div_num = ((uint64_t) LEDC_APB_CLK_HZ << 8) / freq_hz / precision;
|
||||
} else {
|
||||
div_num = ((uint64_t) LEDC_REF_CLK_HZ << 8) / freq_hz / precision;
|
||||
}
|
||||
if(div_num <= 256 || div_num > LEDC_DIV_NUM_HSTIMER0) {
|
||||
LEDC_ERROR("div param err,div_param=%u\n", div_num);
|
||||
ret = ESP_FAIL;
|
||||
}
|
||||
LEDC.timer_group[speed_mode].timer[timer_num].conf.div_num = div_num;
|
||||
portEXIT_CRITICAL(&ledc_spinlock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t ledc_get_freq(ledc_mode_t speed_mode, ledc_timer_t timer_num)
|
||||
{
|
||||
if(!ledc_is_valid_mode(speed_mode)) {
|
||||
return 0;
|
||||
}
|
||||
portENTER_CRITICAL(&ledc_spinlock);
|
||||
uint32_t freq = 0;
|
||||
uint32_t timer_source_clk = LEDC.timer_group[speed_mode].timer[timer_num].conf.tick_sel;
|
||||
uint32_t bit_num = LEDC.timer_group[speed_mode].timer[timer_num].conf.bit_num;
|
||||
uint32_t div_num = LEDC.timer_group[speed_mode].timer[timer_num].conf.div_num;
|
||||
uint32_t precision = (0x1 << bit_num);
|
||||
if(timer_source_clk == LEDC_APB_CLK) {
|
||||
freq = ((uint64_t) LEDC_APB_CLK_HZ << 8) / precision / div_num;
|
||||
} else {
|
||||
freq = ((uint64_t) LEDC_REF_CLK_HZ << 8) / precision / div_num;
|
||||
}
|
||||
portEXIT_CRITICAL(&ledc_spinlock);
|
||||
return freq;
|
||||
}
|
170
components/driver/periph_ctrl.c
Normal file
170
components/driver/periph_ctrl.c
Normal file
|
@ -0,0 +1,170 @@
|
|||
// 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 <esp_types.h>
|
||||
#include "esp_intr.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/xtensa_api.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "driver/periph_ctrl.h"
|
||||
|
||||
static portMUX_TYPE periph_spinlock = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
void periph_module_enable(periph_module_t periph)
|
||||
{
|
||||
portENTER_CRITICAL(&periph_spinlock);
|
||||
switch(periph) {
|
||||
case PERIPH_LEDC_MODULE:
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_LEDC_CLK_EN);
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_LEDC_RST);
|
||||
break;
|
||||
case PERIPH_UART0_MODULE:
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_UART_CLK_EN);
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UART_RST);
|
||||
break;
|
||||
case PERIPH_UART1_MODULE:
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_UART1_CLK_EN);
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UART1_RST);
|
||||
break;
|
||||
case PERIPH_UART2_MODULE:
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_UART2_CLK_EN);
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UART2_RST);
|
||||
break;
|
||||
case PERIPH_I2C0_MODULE:
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2C_EXT0_CLK_EN);
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2C_EXT0_RST);
|
||||
break;
|
||||
case PERIPH_I2C1_MODULE:
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2C_EXT1_CLK_EN);
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2C_EXT1_RST);
|
||||
break;
|
||||
case PERIPH_I2S0_MODULE:
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S0_CLK_EN);
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S0_RST);
|
||||
break;
|
||||
case PERIPH_I2S1_MODULE:
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S1_CLK_EN);
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S1_RST);
|
||||
break;
|
||||
case PERIPH_TIMG0_MODULE:
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_TIMERGROUP_CLK_EN);
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_TIMERGROUP_RST);
|
||||
break;
|
||||
case PERIPH_TIMG1_MODULE:
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_TIMERGROUP1_CLK_EN);
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_TIMERGROUP1_RST);
|
||||
break;
|
||||
case PERIPH_PWM0_MODULE:
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_PWM0_CLK_EN);
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_PWM0_RST);
|
||||
break;
|
||||
case PERIPH_PWM1_MODULE:
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_PWM1_CLK_EN);
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_PWM1_RST);
|
||||
break;
|
||||
case PERIPH_PWM2_MODULE:
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_PWM2_CLK_EN);
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_PWM2_RST);
|
||||
break;
|
||||
case PERIPH_PWM3_MODULE:
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_PWM3_CLK_EN);
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_PWM3_RST);
|
||||
break;
|
||||
case PERIPH_UHCI0_MODULE:
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_UHCI0_CLK_EN);
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UHCI0_RST);
|
||||
break;
|
||||
case PERIPH_UHCI1_MODULE:
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_UHCI1_CLK_EN);
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UHCI1_RST);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
portEXIT_CRITICAL(&periph_spinlock);
|
||||
}
|
||||
|
||||
void periph_module_disable(periph_module_t periph)
|
||||
{
|
||||
portENTER_CRITICAL(&periph_spinlock);
|
||||
switch(periph) {
|
||||
case PERIPH_LEDC_MODULE:
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_LEDC_CLK_EN);
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_LEDC_RST);
|
||||
break;
|
||||
case PERIPH_UART0_MODULE:
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_UART_CLK_EN);
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UART_RST);
|
||||
break;
|
||||
case PERIPH_UART1_MODULE:
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_UART1_CLK_EN);
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UART1_RST);
|
||||
break;
|
||||
case PERIPH_UART2_MODULE:
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_UART2_CLK_EN);
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UART2_RST);
|
||||
break;
|
||||
case PERIPH_I2C0_MODULE:
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2C_EXT0_CLK_EN);
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2C_EXT0_RST);
|
||||
break;
|
||||
case PERIPH_I2C1_MODULE:
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2C_EXT0_CLK_EN);
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2C_EXT1_RST);
|
||||
break;
|
||||
case PERIPH_I2S0_MODULE:
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S0_CLK_EN);
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S0_RST);
|
||||
break;
|
||||
case PERIPH_I2S1_MODULE:
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_I2S1_CLK_EN);
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_I2S1_RST);
|
||||
break;
|
||||
case PERIPH_TIMG0_MODULE:
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_TIMERGROUP_CLK_EN);
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_TIMERGROUP_RST);
|
||||
break;
|
||||
case PERIPH_TIMG1_MODULE:
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_TIMERGROUP1_CLK_EN);
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_TIMERGROUP1_RST);
|
||||
break;
|
||||
case PERIPH_PWM0_MODULE:
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_PWM0_CLK_EN);
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_PWM0_RST);
|
||||
break;
|
||||
case PERIPH_PWM1_MODULE:
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_PWM1_CLK_EN);
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_PWM1_RST);
|
||||
break;
|
||||
case PERIPH_PWM2_MODULE:
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_PWM2_CLK_EN);
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_PWM2_RST);
|
||||
break;
|
||||
case PERIPH_PWM3_MODULE:
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_PWM3_CLK_EN);
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_PWM3_RST);
|
||||
break;
|
||||
case PERIPH_UHCI0_MODULE:
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_UHCI0_CLK_EN);
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UHCI0_RST);
|
||||
break;
|
||||
case PERIPH_UHCI1_MODULE:
|
||||
CLEAR_PERI_REG_MASK(DPORT_PERIP_CLK_EN_REG, DPORT_UHCI1_CLK_EN);
|
||||
SET_PERI_REG_MASK(DPORT_PERIP_RST_EN_REG, DPORT_UHCI1_RST);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
portEXIT_CRITICAL(&periph_spinlock);
|
||||
}
|
|
@ -20,41 +20,88 @@ config ESP32_DEFAULT_CPU_FREQ_MHZ
|
|||
default 160 if ESP32_DEFAULT_CPU_FREQ_160
|
||||
default 240 if ESP32_DEFAULT_CPU_FREQ_240
|
||||
|
||||
config WIFI_ENABLED
|
||||
bool "Enable low-level WiFi stack"
|
||||
choice ESP32_WIFI_OR_BT
|
||||
prompt "Select stack to enable (WiFi or BT)"
|
||||
default ESP32_ENABLE_WIFI
|
||||
help
|
||||
Temporarily, WiFi and BT stacks can not be used at the same time.
|
||||
Select which stack to enable.
|
||||
|
||||
config ESP32_ENABLE_STACK_WIFI
|
||||
bool "WiFi"
|
||||
select WIFI_ENABLED if ESP32_ENABLE_STACK_WIFI
|
||||
config ESP32_ENABLE_STACK_BT
|
||||
bool "BT"
|
||||
select MEMMAP_BT if ESP32_ENABLE_STACK_BT
|
||||
select BT_ENABLED if ESP32_ENABLE_STACK_BT
|
||||
config ESP32_ENABLE_STACK_NONE
|
||||
bool "None"
|
||||
endchoice
|
||||
|
||||
config MEMMAP_BT
|
||||
bool
|
||||
depends on ESP32_ENABLE_STACK_BT
|
||||
help
|
||||
The Bluetooth stack uses memory that cannot be used as generic memory anymore. This
|
||||
reserves the space for that within the memory map of the compiled binary.
|
||||
This option is required to enable BT stack.
|
||||
Temporarily, this option is not compatible with WiFi stack.
|
||||
|
||||
config MEMMAP_SMP
|
||||
bool "Reserve memory for two cores"
|
||||
default "y"
|
||||
help
|
||||
The ESP32 contains two cores. If you plan to only use one, you can disable this item
|
||||
to save some memory. (ToDo: Make this automatically depend on unicore support)
|
||||
|
||||
config MEMMAP_TRACEMEM
|
||||
bool "Use TRAX tracing feature"
|
||||
default "n"
|
||||
help
|
||||
The ESP32 contains a feature which allows you to trace the execution path the processor
|
||||
has taken through the program. This is stored in a chunk of 32K (16K for single-processor)
|
||||
of memory that can't be used for general purposes anymore. Disable this if you do not know
|
||||
what this is.
|
||||
|
||||
# Memory to reverse for trace, used in linker script
|
||||
config TRACEMEM_RESERVE_DRAM
|
||||
hex
|
||||
default 0x8000 if MEMMAP_TRACEMEM
|
||||
default 0x0
|
||||
|
||||
config MEMMAP_SPISRAM
|
||||
bool "Use external SPI SRAM chip as main memory"
|
||||
default "n"
|
||||
help
|
||||
The ESP32 can control an external SPI SRAM chip, adding the memory it contains to the
|
||||
main memory map. Enable this if you have this hardware and want to use it in the same
|
||||
way as on-chip RAM.
|
||||
|
||||
config WIFI_ENABLED
|
||||
bool
|
||||
default "y"
|
||||
depends on ESP32_ENABLE_STACK_WIFI
|
||||
help
|
||||
This compiles in the low-level WiFi stack.
|
||||
|
||||
Temporarily, this option requires that FreeRTOS runs in single core mode.
|
||||
|
||||
config WIFI_AUTO_STARTUP
|
||||
bool "Start WiFi with system startup"
|
||||
default "y"
|
||||
depends on WIFI_ENABLED
|
||||
help
|
||||
By default, WiFi is started with system startup, you can turn off this
|
||||
feature and start by yourself.
|
||||
|
||||
config WIFI_AUTO_CONNECT
|
||||
bool "Enable auto connect"
|
||||
default "y"
|
||||
depends on WIFI_ENABLED
|
||||
help
|
||||
If station is enabled, and station config is set, this will enable WiFi
|
||||
station auto connect when WiFi startup.
|
||||
Temporarily, this option is not compatible with BT stack.
|
||||
|
||||
config SYSTEM_EVENT_QUEUE_SIZE
|
||||
int "system event queue size"
|
||||
int "System event queue size"
|
||||
default 32
|
||||
depends on WIFI_ENABLED
|
||||
help
|
||||
Config system event queue size in different application.
|
||||
|
||||
config SYSTEM_EVENT_TASK_STACK_SIZE
|
||||
int "system event task stack size"
|
||||
int "Event loop task stack size"
|
||||
default 2048
|
||||
depends on WIFI_ENABLED
|
||||
help
|
||||
Config system event task stack size in different application.
|
||||
|
||||
|
||||
config MAIN_TASK_STACK_SIZE
|
||||
int "Main task stack size"
|
||||
default 4096
|
||||
help
|
||||
Config system event task stack size in different application.
|
||||
|
||||
|
@ -69,4 +116,28 @@ config NEWLIB_STDOUT_ADDCR
|
|||
is usually done by an added CR character. Enabling this will make the
|
||||
standard output code automatically add a CR character before a LF.
|
||||
|
||||
config ULP_COPROC_ENABLED
|
||||
bool "Enable Ultra Low Power (ULP) Coprocessor"
|
||||
default "n"
|
||||
help
|
||||
Set to 'y' if you plan to load a firmware for the coprocessor.
|
||||
|
||||
If this option is enabled, further coprocessor configuration will appear in the Components menu.
|
||||
|
||||
config ULP_COPROC_RESERVE_MEM
|
||||
int "RTC slow memory reserved for coprocessor"
|
||||
default 512
|
||||
range 32 8192
|
||||
depends on ULP_COPROC_ENABLED
|
||||
help
|
||||
Bytes of memory to reserve for ULP coprocessor firmware & data.
|
||||
|
||||
Data is reserved at the beginning of RTC slow memory.
|
||||
|
||||
# Set CONFIG_ULP_COPROC_RESERVE_MEM to 0 if ULP is disabled
|
||||
config ULP_COPROC_RESERVE_MEM
|
||||
int
|
||||
default 0
|
||||
depends on !ULP_COPROC_ENABLED
|
||||
|
||||
endmenu
|
||||
|
|
|
@ -10,23 +10,9 @@
|
|||
|
||||
COMPONENT_SRCDIRS := . hwcrypto
|
||||
|
||||
LIBS := crypto core net80211 phy rtc pp wpa wps
|
||||
LIBS := crypto core net80211 phy rtc pp wpa smartconfig
|
||||
|
||||
ifeq ($(CONFIG_MEMMAP_BT),y)
|
||||
ifeq ($(CONFIG_MEMMAP_TRACEMEM),y)
|
||||
LINKER_SCRIPTS = -T esp32.bt.trace.ld
|
||||
else
|
||||
LINKER_SCRIPTS = -T esp32.bt.ld
|
||||
endif
|
||||
else
|
||||
ifeq ($(CONFIG_MEMMAP_TRACEMEM),y)
|
||||
LINKER_SCRIPTS = -T esp32.trace.ld
|
||||
else
|
||||
LINKER_SCRIPTS = -T esp32.ld
|
||||
endif
|
||||
endif
|
||||
|
||||
LINKER_SCRIPTS += -T esp32.common.ld -T esp32.rom.ld -T esp32.peripherals.ld
|
||||
LINKER_SCRIPTS += -T esp32_out.ld -T esp32.common.ld -T esp32.rom.ld -T esp32.peripherals.ld
|
||||
|
||||
COMPONENT_ADD_LDFLAGS := -lesp32 \
|
||||
$(abspath libhal.a) \
|
||||
|
@ -41,7 +27,7 @@ ALL_LIB_FILES := $(patsubst %,$(COMPONENT_PATH)/lib/lib%.a,$(LIBS))
|
|||
|
||||
# automatically trigger a git submodule update
|
||||
# if any libraries are missing
|
||||
$(eval $(call SubmoduleRequiredForFiles,$(ALL_LIB_FILES)))
|
||||
$(eval $(call SubmoduleCheck,$(ALL_LIB_FILES),$(COMPONENT_PATH)/lib))
|
||||
|
||||
# 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
|
||||
|
@ -51,3 +37,14 @@ $(eval $(call SubmoduleRequiredForFiles,$(ALL_LIB_FILES)))
|
|||
# It would be better for components to be able to expose any of these
|
||||
# non-standard dependencies via get_variable, but this will do for now.
|
||||
$(COMPONENT_LIBRARY): $(ALL_LIB_FILES)
|
||||
|
||||
# Preprocess esp32.ld linker script into esp32_out.ld
|
||||
#
|
||||
# The library doesn't really depend on esp32_out.ld, but it
|
||||
# saves us from having to add the target to a Makefile.projbuild
|
||||
$(COMPONENT_LIBRARY): esp32_out.ld
|
||||
|
||||
esp32_out.ld: $(COMPONENT_PATH)/ld/esp32.ld ../include/sdkconfig.h
|
||||
$(CC) -I ../include -C -P -x c -E $< -o $@
|
||||
|
||||
COMPONENT_EXTRA_CLEAN := esp32_out.ld
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include "rom/ets_sys.h"
|
||||
#include "rom/uart.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
typedef enum{
|
||||
|
@ -42,10 +43,15 @@ extern void rtc_set_cpu_freq(xtal_freq_t xtal_freq, cpu_freq_t cpu_freq);
|
|||
* components which want to be notified of CPU frequency
|
||||
* changes.
|
||||
*/
|
||||
void esp_set_cpu_freq()
|
||||
void esp_set_cpu_freq(void)
|
||||
{
|
||||
uint32_t freq_mhz = CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ;
|
||||
phy_get_romfunc_addr();
|
||||
|
||||
// freq will be changed to 40MHz in rtc_init_lite,
|
||||
// wait uart tx finish, otherwise some uart output will be lost
|
||||
uart_tx_wait_idle(0);
|
||||
|
||||
rtc_init_lite();
|
||||
cpu_freq_t freq = CPU_80M;
|
||||
switch(freq_mhz) {
|
||||
|
@ -62,6 +68,11 @@ void esp_set_cpu_freq()
|
|||
freq = CPU_80M;
|
||||
break;
|
||||
}
|
||||
|
||||
// freq will be changed to freq in rtc_set_cpu_freq,
|
||||
// wait uart tx finish, otherwise some uart output will be lost
|
||||
uart_tx_wait_idle(0);
|
||||
|
||||
rtc_set_cpu_freq(XTAL_AUTO, freq);
|
||||
ets_update_cpu_frequency(freq_mhz);
|
||||
}
|
||||
|
|
|
@ -43,11 +43,19 @@
|
|||
#include "esp_ipc.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
static void IRAM_ATTR user_start_cpu0(void);
|
||||
static void IRAM_ATTR call_user_start_cpu1();
|
||||
static void IRAM_ATTR user_start_cpu1(void);
|
||||
void start_cpu0(void) __attribute__((weak, alias("start_cpu0_default")));
|
||||
void start_cpu0_default(void) IRAM_ATTR;
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
static void IRAM_ATTR call_start_cpu1();
|
||||
void start_cpu1(void) __attribute__((weak, alias("start_cpu1_default")));
|
||||
void start_cpu1_default(void) IRAM_ATTR;
|
||||
static bool app_cpu_started = false;
|
||||
#endif //!CONFIG_FREERTOS_UNICORE
|
||||
|
||||
static void do_global_ctors(void);
|
||||
static void main_task(void* args);
|
||||
extern void ets_setup_syscalls(void);
|
||||
extern esp_err_t app_main(void *ctx);
|
||||
extern void app_main(void);
|
||||
|
||||
extern int _bss_start;
|
||||
extern int _bss_end;
|
||||
|
@ -57,14 +65,13 @@ extern void (*__init_array_end)(void);
|
|||
extern volatile int port_xSchedulerRunning[2];
|
||||
|
||||
static const char* TAG = "cpu_start";
|
||||
static bool app_cpu_started = false;
|
||||
|
||||
/*
|
||||
* We arrive here after the bootloader finished loading the program from flash. The hardware is mostly uninitialized,
|
||||
* and the app CPU is in reset. We do have a stack, so we can do the initialization in C.
|
||||
*/
|
||||
|
||||
void IRAM_ATTR call_user_start_cpu0()
|
||||
void IRAM_ATTR call_start_cpu0()
|
||||
{
|
||||
//Kill wdt
|
||||
REG_CLR_BIT(RTC_CNTL_WDTCONFIG0_REG, RTC_CNTL_WDT_FLASHBOOT_MOD_EN);
|
||||
|
@ -87,14 +94,14 @@ void IRAM_ATTR call_user_start_cpu0()
|
|||
|
||||
ESP_EARLY_LOGI(TAG, "Pro cpu up.");
|
||||
|
||||
#ifndef CONFIG_FREERTOS_UNICORE
|
||||
ESP_EARLY_LOGI(TAG, "Starting app cpu, entry point is %p", call_user_start_cpu1);
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
ESP_EARLY_LOGI(TAG, "Starting app cpu, entry point is %p", call_start_cpu1);
|
||||
|
||||
SET_PERI_REG_MASK(DPORT_APPCPU_CTRL_B_REG, DPORT_APPCPU_CLKGATE_EN);
|
||||
CLEAR_PERI_REG_MASK(DPORT_APPCPU_CTRL_C_REG, DPORT_APPCPU_RUNSTALL);
|
||||
SET_PERI_REG_MASK(DPORT_APPCPU_CTRL_A_REG, DPORT_APPCPU_RESETTING);
|
||||
CLEAR_PERI_REG_MASK(DPORT_APPCPU_CTRL_A_REG, DPORT_APPCPU_RESETTING);
|
||||
ets_set_appcpu_boot_addr((uint32_t)call_user_start_cpu1);
|
||||
ets_set_appcpu_boot_addr((uint32_t)call_start_cpu1);
|
||||
|
||||
while (!app_cpu_started) {
|
||||
ets_delay_us(100);
|
||||
|
@ -104,11 +111,11 @@ void IRAM_ATTR call_user_start_cpu0()
|
|||
CLEAR_PERI_REG_MASK(DPORT_APPCPU_CTRL_B_REG, DPORT_APPCPU_CLKGATE_EN);
|
||||
#endif
|
||||
ESP_EARLY_LOGI(TAG, "Pro cpu start user code");
|
||||
user_start_cpu0();
|
||||
start_cpu0();
|
||||
}
|
||||
|
||||
|
||||
void IRAM_ATTR call_user_start_cpu1()
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
void IRAM_ATTR call_start_cpu1()
|
||||
{
|
||||
asm volatile (\
|
||||
"wsr %0, vecbase\n" \
|
||||
|
@ -118,10 +125,27 @@ void IRAM_ATTR call_user_start_cpu1()
|
|||
|
||||
ESP_EARLY_LOGI(TAG, "App cpu up.");
|
||||
app_cpu_started = 1;
|
||||
user_start_cpu1();
|
||||
start_cpu1();
|
||||
}
|
||||
#endif //!CONFIG_FREERTOS_UNICORE
|
||||
|
||||
void start_cpu0_default(void)
|
||||
{
|
||||
esp_set_cpu_freq(); // set CPU frequency configured in menuconfig
|
||||
uart_div_modify(0, (APB_CLK_FREQ << 4) / 115200);
|
||||
ets_setup_syscalls();
|
||||
do_global_ctors();
|
||||
esp_ipc_init();
|
||||
spi_flash_init();
|
||||
xTaskCreatePinnedToCore(&main_task, "main",
|
||||
ESP_TASK_MAIN_STACK, NULL,
|
||||
ESP_TASK_MAIN_PRIO, NULL, 0);
|
||||
ESP_LOGI(TAG, "Starting scheduler on PRO CPU.");
|
||||
vTaskStartScheduler();
|
||||
}
|
||||
|
||||
void IRAM_ATTR user_start_cpu1(void)
|
||||
#if !CONFIG_FREERTOS_UNICORE
|
||||
void start_cpu1_default(void)
|
||||
{
|
||||
// Wait for FreeRTOS initialization to finish on PRO CPU
|
||||
while (port_xSchedulerRunning[0] == 0) {
|
||||
|
@ -130,43 +154,19 @@ void IRAM_ATTR user_start_cpu1(void)
|
|||
ESP_LOGI(TAG, "Starting scheduler on APP CPU.");
|
||||
xPortStartScheduler();
|
||||
}
|
||||
#endif //!CONFIG_FREERTOS_UNICORE
|
||||
|
||||
static void do_global_ctors(void)
|
||||
{
|
||||
void (**p)(void);
|
||||
for (p = &__init_array_start; p != &__init_array_end; ++p) {
|
||||
for (p = &__init_array_end - 1; p >= &__init_array_start; --p) {
|
||||
(*p)();
|
||||
}
|
||||
}
|
||||
|
||||
void user_start_cpu0(void)
|
||||
static void main_task(void* args)
|
||||
{
|
||||
esp_set_cpu_freq(); // set CPU frequency configured in menuconfig
|
||||
uart_div_modify(0, (APB_CLK_FREQ << 4) / 115200);
|
||||
ets_setup_syscalls();
|
||||
do_global_ctors();
|
||||
esp_ipc_init();
|
||||
spi_flash_init();
|
||||
|
||||
#if CONFIG_WIFI_ENABLED
|
||||
esp_err_t ret = nvs_flash_init(5, 3);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "nvs_flash_init failed, ret=%d", ret);
|
||||
}
|
||||
|
||||
system_init();
|
||||
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, NULL);
|
||||
#else
|
||||
app_main(NULL);
|
||||
#endif
|
||||
|
||||
ESP_LOGI(TAG, "Starting scheduler on PRO CPU.");
|
||||
vTaskStartScheduler();
|
||||
app_main();
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
|
|
49
components/esp32/deepsleep.c
Normal file
49
components/esp32/deepsleep.c
Normal file
|
@ -0,0 +1,49 @@
|
|||
/* Wake from deep sleep stub
|
||||
|
||||
See esp_deepsleep.h esp_wake_deep_sleep() comments for details.
|
||||
*/
|
||||
#include <stddef.h>
|
||||
#include <sys/lock.h>
|
||||
#include "rom/cache.h"
|
||||
#include "rom/rtc.h"
|
||||
#include "soc/rtc_cntl_reg.h"
|
||||
#include "soc/dport_reg.h"
|
||||
#include "esp_attr.h"
|
||||
#include "esp_deepsleep.h"
|
||||
|
||||
/* Updating RTC_MEMORY_CRC_REG register via set_rtc_memory_crc()
|
||||
is not thread-safe. */
|
||||
static _lock_t lock_rtc_memory_crc;
|
||||
|
||||
esp_deep_sleep_wake_stub_fn_t esp_get_deep_sleep_wake_stub(void)
|
||||
{
|
||||
_lock_acquire(&lock_rtc_memory_crc);
|
||||
uint32_t stored_crc = REG_READ(RTC_MEMORY_CRC_REG);
|
||||
set_rtc_memory_crc();
|
||||
uint32_t calc_crc = REG_READ(RTC_MEMORY_CRC_REG);
|
||||
REG_WRITE(RTC_MEMORY_CRC_REG, stored_crc);
|
||||
_lock_release(&lock_rtc_memory_crc);
|
||||
|
||||
if(stored_crc == calc_crc) {
|
||||
return (esp_deep_sleep_wake_stub_fn_t)REG_READ(RTC_ENTRY_ADDR_REG);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void esp_set_deep_sleep_wake_stub(esp_deep_sleep_wake_stub_fn_t new_stub)
|
||||
{
|
||||
_lock_acquire(&lock_rtc_memory_crc);
|
||||
REG_WRITE(RTC_ENTRY_ADDR_REG, (uint32_t)new_stub);
|
||||
set_rtc_memory_crc();
|
||||
_lock_release(&lock_rtc_memory_crc);
|
||||
}
|
||||
|
||||
void RTC_IRAM_ATTR esp_default_wake_deep_sleep(void) {
|
||||
//
|
||||
//mmu_init(0);
|
||||
REG_SET_BIT(DPORT_PRO_CACHE_CTRL1_REG, DPORT_PRO_CACHE_MMU_IA_CLR);
|
||||
REG_CLR_BIT(DPORT_PRO_CACHE_CTRL1_REG, DPORT_PRO_CACHE_MMU_IA_CLR);
|
||||
}
|
||||
|
||||
void __attribute__((weak, alias("esp_default_wake_deep_sleep"))) esp_wake_deep_sleep(void);
|
|
@ -19,6 +19,7 @@
|
|||
#include "esp_err.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_event_loop.h"
|
||||
#include "esp_task.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
|
@ -27,22 +28,15 @@
|
|||
#include "freertos/semphr.h"
|
||||
|
||||
#include "tcpip_adapter.h"
|
||||
#include "esp_log.h"
|
||||
|
||||
#define ESP32_WORKAROUND 1
|
||||
const char* TAG = "event";
|
||||
|
||||
#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;
|
||||
static void *g_event_ctx;
|
||||
|
||||
#define WIFI_DEBUG(...)
|
||||
#define WIFI_API_CALL_CHECK(info, api_call, ret) \
|
||||
do{\
|
||||
esp_err_t __err = (api_call);\
|
||||
if ((ret) != __err) {\
|
||||
WIFI_DEBUG("%s %d %s ret=%d\n", __FUNCTION__, __LINE__, (info), __err);\
|
||||
ESP_LOGE(TAG, "%s %d %s ret=%d", __FUNCTION__, __LINE__, (info), __err);\
|
||||
return __err;\
|
||||
}\
|
||||
} while(0)
|
||||
|
@ -85,7 +79,7 @@ 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",
|
||||
ESP_LOGI(TAG, "ip: " IPSTR ", mask: " IPSTR ", gw: " IPSTR,
|
||||
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));
|
||||
|
@ -161,7 +155,7 @@ esp_err_t system_event_sta_connected_handle_default(system_event_t *event)
|
|||
|
||||
esp_event_send(&evt);
|
||||
} else {
|
||||
WIFI_DEBUG("invalid static ip\n");
|
||||
ESP_LOGE(TAG, "invalid static ip");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -175,104 +169,89 @@ esp_err_t system_event_sta_disconnected_handle_default(system_event_t *event)
|
|||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t esp_wifi_post_event_to_user(system_event_t *event)
|
||||
{
|
||||
if (g_event_handler_cb) {
|
||||
return (*g_event_handler_cb)(g_event_ctx, event);
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t esp_system_event_debug(system_event_t *event)
|
||||
{
|
||||
if (event == NULL) {
|
||||
printf("Error: event is null!\n");
|
||||
ESP_LOGE(TAG, "event is null!");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
WIFI_DEBUG("received event: ");
|
||||
switch (event->event_id) {
|
||||
case SYSTEM_EVENT_WIFI_READY: {
|
||||
WIFI_DEBUG("SYSTEM_EVENT_WIFI_READY\n");
|
||||
ESP_LOGD(TAG, "SYSTEM_EVENT_WIFI_READY");
|
||||
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);
|
||||
system_event_sta_scan_done_t *scan_done = &event->event_info.scan_done;
|
||||
ESP_LOGD(TAG, "SYSTEM_EVENT_SCAN_DONE, status:%d, number:%d", scan_done->status, scan_done->number);
|
||||
break;
|
||||
}
|
||||
case SYSTEM_EVENT_STA_START: {
|
||||
WIFI_DEBUG("SYSTEM_EVENT_STA_START\n");
|
||||
ESP_LOGD(TAG, "SYSTEM_EVENT_STA_START");
|
||||
break;
|
||||
}
|
||||
case SYSTEM_EVENT_STA_STOP: {
|
||||
WIFI_DEBUG("SYSTEM_EVENT_STA_STOP\n");
|
||||
ESP_LOGD(TAG, "SYSTEM_EVENT_STA_STOP");
|
||||
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", \
|
||||
system_event_sta_connected_t *connected = &event->event_info.connected;
|
||||
ESP_LOGD(TAG, "SYSTEM_EVENT_STA_CONNECTED, ssid:%s, ssid_len:%d, bssid:%02x:%02x:%02x:%02x:%02x:%02x, channel:%d, authmode:%d", \
|
||||
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", \
|
||||
system_event_sta_disconnected_t *disconnected = &event->event_info.disconnected;
|
||||
ESP_LOGD(TAG, "SYSTEM_EVENT_STA_DISCONNECTED, ssid:%s, ssid_len:%d, bssid:%02x:%02x:%02x:%02x:%02x:%02x, reason:%d", \
|
||||
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);
|
||||
system_event_sta_authmode_change_t *auth_change = &event->event_info.auth_change;
|
||||
ESP_LOGD(TAG, "SYSTEM_EVENT_STA_AUTHMODE_CHNAGE, old_mode:%d, new_mode:%d", 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");
|
||||
system_event_sta_got_ip_t *got_ip = &event->event_info.got_ip;
|
||||
ESP_LOGD(TAG, "SYSTEM_EVENT_STA_GOTIP, ip:" IPSTR ", mask:" IPSTR ", gw:" IPSTR,
|
||||
IP2STR(&got_ip->ip_info.ip),
|
||||
IP2STR(&got_ip->ip_info.netmask),
|
||||
IP2STR(&got_ip->ip_info.gw));
|
||||
break;
|
||||
}
|
||||
case SYSTEM_EVENT_AP_START: {
|
||||
WIFI_DEBUG("SYSTEM_EVENT_AP_START\n");
|
||||
ESP_LOGD(TAG, "SYSTEM_EVENT_AP_START");
|
||||
break;
|
||||
}
|
||||
case SYSTEM_EVENT_AP_STOP: {
|
||||
WIFI_DEBUG("SYSTEM_EVENT_AP_STOP\n");
|
||||
ESP_LOGD(TAG, "SYSTEM_EVENT_AP_STOP");
|
||||
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", \
|
||||
system_event_ap_staconnected_t *staconnected = &event->event_info.sta_connected;
|
||||
ESP_LOGD(TAG, "SYSTEM_EVENT_AP_STACONNECTED, mac:%02x:%02x:%02x:%02x:%02x:%02x, aid:%d", \
|
||||
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", \
|
||||
system_event_ap_stadisconnected_t *stadisconnected = &event->event_info.sta_disconnected;
|
||||
ESP_LOGD(TAG, "SYSTEM_EVENT_AP_STADISCONNECTED, mac:%02x:%02x:%02x:%02x:%02x:%02x, aid:%d", \
|
||||
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", \
|
||||
system_event_ap_probe_req_rx_t *ap_probereqrecved = &event->event_info.ap_probereqrecved;
|
||||
ESP_LOGD(TAG, "SYSTEM_EVENT_AP_PROBEREQRECVED, rssi:%d, mac:%02x:%02x:%02x:%02x:%02x:%02x", \
|
||||
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");
|
||||
ESP_LOGW(TAG, "no such kind of event!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -280,88 +259,23 @@ static esp_err_t esp_system_event_debug(system_event_t *event)
|
|||
return ESP_OK;
|
||||
}
|
||||
|
||||
static esp_err_t esp_system_event_handler(system_event_t *event)
|
||||
esp_err_t esp_event_process_default(system_event_t *event)
|
||||
{
|
||||
if (event == NULL) {
|
||||
printf("Error: event is null!\n");
|
||||
ESP_LOGE(TAG, "Error: event is null!");
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
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) {
|
||||
WIFI_DEBUG("enter default callback\n");
|
||||
ESP_LOGV(TAG, "enter default callback");
|
||||
g_system_event_handle_table[event->event_id].event_handle(event);
|
||||
WIFI_DEBUG("exit default callback\n");
|
||||
ESP_LOGV(TAG, "exit default callback");
|
||||
}
|
||||
} else {
|
||||
printf("mismatch or invalid event, id=%d\n", event->event_id);
|
||||
}
|
||||
|
||||
return esp_wifi_post_event_to_user(event);
|
||||
}
|
||||
|
||||
static void esp_system_event_task(void *pvParameters)
|
||||
{
|
||||
system_event_t evt;
|
||||
esp_err_t ret;
|
||||
|
||||
while (1) {
|
||||
if (xQueueReceive(g_event_handler, &evt, portMAX_DELAY) == pdPASS) {
|
||||
ret = esp_system_event_handler(&evt);
|
||||
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, 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");
|
||||
}
|
||||
ESP_LOGE(TAG, "mismatch or invalid event, id=%d", event->event_id);
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
void *esp_event_get_handler(void)
|
||||
{
|
||||
return (void *)g_event_handler;
|
||||
}
|
||||
|
||||
esp_err_t esp_event_init(system_event_cb_t cb, void *ctx)
|
||||
{
|
||||
if (event_init_flag) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
|
||||
g_event_handler_cb = cb;
|
||||
g_event_ctx = ctx;
|
||||
|
||||
g_event_handler = xQueueCreate(CONFIG_SYSTEM_EVENT_QUEUE_SIZE, sizeof(system_event_t));
|
||||
|
||||
xTaskCreatePinnedToCore(esp_system_event_task, "eventTask", ESP_TASKD_EVENT_STACK, NULL, ESP_TASKD_EVENT_PRIO, NULL, 0);
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
#endif
|
107
components/esp32/event_loop.c
Normal file
107
components/esp32/event_loop.c
Normal file
|
@ -0,0 +1,107 @@
|
|||
// 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 "esp_err.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_event_loop.h"
|
||||
#include "esp_task.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/semphr.h"
|
||||
|
||||
#include "esp_log.h"
|
||||
#include "sdkconfig.h"
|
||||
|
||||
|
||||
static const char* TAG = "event";
|
||||
static bool s_event_init_flag = false;
|
||||
static QueueHandle_t s_event_queue = NULL;
|
||||
static system_event_cb_t s_event_handler_cb = NULL;
|
||||
static void *s_event_ctx = NULL;
|
||||
|
||||
static esp_err_t esp_event_post_to_user(system_event_t *event)
|
||||
{
|
||||
if (s_event_handler_cb) {
|
||||
return (*s_event_handler_cb)(s_event_ctx, event);
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
static void esp_event_loop_task(void *pvParameters)
|
||||
{
|
||||
while (1) {
|
||||
system_event_t evt;
|
||||
if (xQueueReceive(s_event_queue, &evt, portMAX_DELAY) == pdPASS) {
|
||||
esp_err_t ret = esp_event_process_default(&evt);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "default event handler failed!");
|
||||
}
|
||||
ret = esp_event_post_to_user(&evt);
|
||||
if (ret != ESP_OK) {
|
||||
ESP_LOGE(TAG, "post event to user fail!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
system_event_cb_t esp_event_loop_set_cb(system_event_cb_t cb, void *ctx)
|
||||
{
|
||||
system_event_cb_t old_cb = s_event_handler_cb;
|
||||
s_event_handler_cb = cb;
|
||||
s_event_ctx = ctx;
|
||||
return old_cb;
|
||||
}
|
||||
|
||||
esp_err_t esp_event_send(system_event_t *event)
|
||||
{
|
||||
portBASE_TYPE ret = xQueueSendToBack(s_event_queue, event, 0);
|
||||
if (ret != pdPASS) {
|
||||
if (event) {
|
||||
ESP_LOGE(TAG, "e=%d f", event->event_id);
|
||||
} else {
|
||||
ESP_LOGE(TAG, "e null");
|
||||
}
|
||||
return ESP_FAIL;
|
||||
}
|
||||
return ESP_OK;
|
||||
}
|
||||
|
||||
QueueHandle_t esp_event_loop_get_queue(void)
|
||||
{
|
||||
return s_event_queue;
|
||||
}
|
||||
|
||||
esp_err_t esp_event_loop_init(system_event_cb_t cb, void *ctx)
|
||||
{
|
||||
if (s_event_init_flag) {
|
||||
return ESP_FAIL;
|
||||
}
|
||||
s_event_handler_cb = cb;
|
||||
s_event_ctx = ctx;
|
||||
s_event_queue = xQueueCreate(CONFIG_SYSTEM_EVENT_QUEUE_SIZE, sizeof(system_event_t));
|
||||
|
||||
xTaskCreatePinnedToCore(esp_event_loop_task, "eventTask",
|
||||
ESP_TASKD_EVENT_STACK, NULL, ESP_TASKD_EVENT_PRIO, NULL, 0);
|
||||
|
||||
s_event_init_flag = true;
|
||||
return ESP_OK;
|
||||
}
|
||||
|
|
@ -17,8 +17,8 @@
|
|||
#define ROMFN_ATTR
|
||||
|
||||
//Normally, the linker script will put all code and rodata in flash,
|
||||
//and all variables in shared RAM. This can be redirected to IRAM if
|
||||
//needed using these macros.
|
||||
//and all variables in shared RAM. These macros can be used to redirect
|
||||
//particular functions/variables to other memory regions.
|
||||
|
||||
// Forces code into IRAM instead of flash
|
||||
#define IRAM_ATTR __attribute__((section(".iram1")))
|
||||
|
@ -26,4 +26,16 @@
|
|||
// Forces data into DRAM instead of flash
|
||||
#define DRAM_ATTR __attribute__((section(".dram1")))
|
||||
|
||||
// Forces code into RTC fast memory
|
||||
#define RTC_IRAM_ATTR __attribute__((section(".rtc.text")))
|
||||
|
||||
// Forces data into RTC slow memory
|
||||
// Any variable marked with this attribute will keep its value
|
||||
// during a deep sleep / wake cycle.
|
||||
#define RTC_DATA_ATTR __attribute__((section(".rtc.data")))
|
||||
|
||||
// Forces read-only data into RTC slow memory
|
||||
// Makes constant data available to RTC wake stubs (see esp_deepsleep.h)
|
||||
#define RTC_RODATA_ATTR __attribute__((section(".rtc.rodata")))
|
||||
|
||||
#endif /* __ESP_ATTR_H__ */
|
||||
|
|
137
components/esp32/include/esp_deepsleep.h
Normal file
137
components/esp32/include/esp_deepsleep.h
Normal file
|
@ -0,0 +1,137 @@
|
|||
// 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_DEEPSLEEP_H__
|
||||
#define __ESP_DEEPSLEEP_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup Deep_Sleep_API Deep Sleep API
|
||||
* @brief API for putting device into deep sleep
|
||||
*/
|
||||
|
||||
/** @addtogroup Deep_Sleep_API
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief Set the chip to deep-sleep mode.
|
||||
*
|
||||
* The device will automatically wake up after the deep-sleep time set
|
||||
* by the users. Upon waking up, the device boots up from user_init.
|
||||
*
|
||||
* @attention The parameter time_in_us to be "uint64" is for further development.
|
||||
* Only the low 32 bits of parameter time_in_us are avalable now.
|
||||
*
|
||||
* @param uint64 time_in_us : deep-sleep time, only the low 32bits are avalable now. unit: microsecond
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
void system_deep_sleep(uint64_t time_in_us);
|
||||
|
||||
/**
|
||||
* @brief Default stub to run on wake from deep sleep.
|
||||
*
|
||||
* Allows for executing code immediately on wake from sleep, before
|
||||
* the software bootloader or esp-idf app has started up.
|
||||
*
|
||||
* This function is weak-linked, so you can implement your own version
|
||||
* to run code immediately when the chip wakes from
|
||||
* sleep.
|
||||
*
|
||||
* For example:
|
||||
* @code
|
||||
* void RTC_IRAM_ATTR esp_wake_deep_sleep(void) {
|
||||
* esp_default_wake_deep_sleep();
|
||||
* // Add additional functionality here
|
||||
* }
|
||||
*
|
||||
* (Implementing this function is not required for normal operation,
|
||||
* in the usual case your app will start normally when waking from
|
||||
* deep sleep.)
|
||||
*
|
||||
* esp_wake_deep_sleep() functionality is limited:
|
||||
*
|
||||
* - Runs immediately on wake, so most of the SoC is freshly reset -
|
||||
* flash is unmapped and hardware is otherwise uninitialised.
|
||||
*
|
||||
* - Can only call functions implemented in ROM, or marked RTC_IRAM_ATTR.
|
||||
*
|
||||
* - Static variables marked RTC_DATA_ATTR will have initial values on
|
||||
* cold boot, and maintain these values between sleep/wake cycles.
|
||||
*
|
||||
* - Read-only data should be marked RTC_RODATA_ATTR. Strings must be
|
||||
* declared as variables also using RTC_RODATA_ATTR, like this:
|
||||
* RTC_RODATA_ATTR const char message[] = "Hello from very early boot!\n";
|
||||
*
|
||||
* - Any other static memory will not be initialised (either to zero,
|
||||
* or to any predefined value).
|
||||
*
|
||||
*
|
||||
* - If you implement your own stub, the first call the stub makes
|
||||
should be to esp_default_wake_deep_sleep().
|
||||
*/
|
||||
void esp_wake_deep_sleep(void);
|
||||
|
||||
/**
|
||||
* @brief Function type for stub to run on wake from sleep.
|
||||
*
|
||||
*/
|
||||
typedef void (*esp_deep_sleep_wake_stub_fn_t)(void);
|
||||
|
||||
/**
|
||||
* @brief Install a new stub at runtime to run on wake from deep sleep
|
||||
*
|
||||
* If implementing esp_wake_deep_sleep() then it is not necessary to
|
||||
* call this function.
|
||||
*
|
||||
* However, it is possible to call this function to substitute a
|
||||
* different deep sleep stub. Any function used as a deep sleep stub
|
||||
* must be marked RTC_IRAM_ATTR, and must obey the same rules given
|
||||
* for esp_wake_deep_sleep().
|
||||
*/
|
||||
void esp_set_deep_sleep_wake_stub(esp_deep_sleep_wake_stub_fn_t new_stub);
|
||||
|
||||
/**
|
||||
* @brief Return current wake from deep sleep stub, or NULL if
|
||||
* no stub is installed.
|
||||
*/
|
||||
esp_deep_sleep_wake_stub_fn_t esp_get_deep_sleep_wake_stub(void);
|
||||
|
||||
/* The default esp-idf-provided esp_wake_deep_sleep() stub.
|
||||
|
||||
If you replace esp_wake_deep_sleep() in your program, or use
|
||||
esp_set_deep_sleep_wake_stub(), then it is recommended you call
|
||||
esp_default_wake_deep_sleep() as the first function in your stub.
|
||||
*/
|
||||
void esp_default_wake_deep_sleep(void);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ESP_SYSTEM_H__ */
|
|
@ -15,6 +15,7 @@
|
|||
#define __ESP_ERR_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -31,6 +32,12 @@ typedef int32_t esp_err_t;
|
|||
#define ESP_ERR_INVALID_ARG 0x102
|
||||
#define ESP_ERR_INVALID_STATE 0x103
|
||||
|
||||
/**
|
||||
* Macro which can be used to check the error code,
|
||||
* and terminate the program in case the code is not ESP_OK.
|
||||
* Prints the failed statement to serial output.
|
||||
*/
|
||||
#define ESP_ERROR_CHECK(x) do { esp_err_t rc = (x); if (rc != ESP_OK) { assert(0 && #x);} } while(0);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -19,8 +19,7 @@
|
|||
#include <stdbool.h>
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_wifi.h"
|
||||
|
||||
#include "esp_wifi_types.h"
|
||||
#include "tcpip_adapter.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -101,33 +100,11 @@ typedef union {
|
|||
} system_event_info_t;
|
||||
|
||||
typedef struct {
|
||||
system_event_id_t event_id; /**< even ID */
|
||||
system_event_id_t event_id; /**< event ID */
|
||||
system_event_info_t event_info; /**< event information */
|
||||
} system_event_t;
|
||||
|
||||
/**
|
||||
* @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);
|
||||
typedef esp_err_t (*system_event_handler_t)(system_event_t *event);
|
||||
|
||||
/**
|
||||
* @brief Send a event to event task
|
||||
|
@ -142,28 +119,20 @@ system_event_cb_t esp_event_set_cb(system_event_cb_t cb, void *ctx);
|
|||
esp_err_t esp_event_send(system_event_t *event);
|
||||
|
||||
/**
|
||||
* @brief Get the event handler
|
||||
* @brief Default event handler for system events
|
||||
*
|
||||
* @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.
|
||||
* This function performs default handling of system events.
|
||||
* When using esp_event_loop APIs, it is called automatically before invoking the user-provided
|
||||
* callback function.
|
||||
*
|
||||
* @param null
|
||||
* Applications which implement a custom event loop must call this function
|
||||
* as part of event processing.
|
||||
*
|
||||
* @return void * : event queue pointer
|
||||
* @param event pointer to event to be handled
|
||||
* @return ESP_OK if an event was handled successfully
|
||||
*/
|
||||
void *esp_event_get_handler(void);
|
||||
esp_err_t esp_event_process_default(system_event_t *event);
|
||||
|
||||
/**
|
||||
* @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
|
||||
}
|
||||
|
|
81
components/esp32/include/esp_event_loop.h
Normal file
81
components/esp32/include/esp_event_loop.h
Normal file
|
@ -0,0 +1,81 @@
|
|||
// 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_EVENT_LOOP_H__
|
||||
#define __ESP_EVENT_LOOP_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_event.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/queue.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @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 Initialize event loop
|
||||
* 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_loop_init(system_event_cb_t cb, void *ctx);
|
||||
|
||||
/**
|
||||
* @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_loop_set_cb(system_event_cb_t cb, void *ctx);
|
||||
|
||||
/**
|
||||
* @brief Get the queue used by event loop
|
||||
*
|
||||
* @attention : currently this API is used to initialize "q" parameter
|
||||
* of wifi_init structure.
|
||||
*
|
||||
* @return QueueHandle_t : event queue handle
|
||||
*/
|
||||
QueueHandle_t esp_event_loop_get_queue(void);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ESP_EVENT_LOOP_H__ */
|
143
components/esp32/include/esp_smartconfig.h
Normal file
143
components/esp32/include/esp_smartconfig.h
Normal file
|
@ -0,0 +1,143 @@
|
|||
// 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_SMARTCONFIG_H__
|
||||
#define __ESP_SMARTCONFIG_H__
|
||||
#include <stdint.h>
|
||||
#include <esp_types.h>
|
||||
#include "esp_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
SC_STATUS_WAIT = 0, /**< waiting, do not start connection in this phase */
|
||||
SC_STATUS_FIND_CHANNEL, /**< find target channel, start connection by APP in this phase */
|
||||
SC_STATUS_GETTING_SSID_PSWD, /**< getting SSID and password of target AP */
|
||||
SC_STATUS_LINK, /**< connecting to target AP */
|
||||
SC_STATUS_LINK_OVER, /**< got IP, connect to AP successfully */
|
||||
} smartconfig_status_t;
|
||||
|
||||
typedef enum {
|
||||
SC_TYPE_ESPTOUCH = 0, /**< protocol: ESPTouch */
|
||||
SC_TYPE_AIRKISS, /**< protocol: AirKiss */
|
||||
SC_TYPE_ESPTOUCH_AIRKISS, /**< protocol: ESPTouch and AirKiss */
|
||||
} smartconfig_type_t;
|
||||
|
||||
/**
|
||||
* @brief The callback of SmartConfig, executed when smart-config status changed.
|
||||
*
|
||||
* @param smartconfig_status_t status : status of SmartConfig:
|
||||
* - if status == SC_STATUS_GETTING_SSID_PSWD, parameter void *pdata is a pointer
|
||||
of smartconfig_type_t, means SmartConfig type: AirKiss or ESP-TOUCH.
|
||||
* - if status == SC_STATUS_LINK, parameter void *pdata is a pointer of struct station_config;
|
||||
* - if status == SC_STATUS_LINK_OVER, parameter void *pdata is a pointer of mobile
|
||||
* phone's IP address, 4 bytes. This is only available in ESPTOUCH, otherwise,
|
||||
* it is NULL.
|
||||
* - otherwise, parameter void *pdata is NULL.
|
||||
* @param void *pdata : data of SmartConfig
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
typedef void (*sc_callback_t)(smartconfig_status_t status, void *pdata);
|
||||
|
||||
/**
|
||||
* @brief Get the version of SmartConfig.
|
||||
*
|
||||
* @param null
|
||||
*
|
||||
* @return SmartConfig version
|
||||
*/
|
||||
const char *esp_smartconfig_get_version(void);
|
||||
|
||||
/**
|
||||
* @brief Start SmartConfig mode.
|
||||
*
|
||||
* Start SmartConfig mode, to connect ESP32 station to AP, by sniffing
|
||||
* for special packets from the air, containing SSID and password of desired AP.
|
||||
* You need to broadcast the SSID and password (e.g. from mobile device or computer)
|
||||
* with the SSID and password encoded.
|
||||
*
|
||||
* @attention 1. This API can only be called in station mode.
|
||||
* @attention 2. During SmartConfig, ESP32 station and soft-AP are disabled.
|
||||
* @attention 3. Can not call esp_smartconfig_start twice before it finish, please call
|
||||
* esp_smartconfig_stop first.
|
||||
* @attention 4. Don't call any other APIs during SmartConfig, please call esp_smartconfig_stop first.
|
||||
*
|
||||
* @param sc_callback_t cb : SmartConfig callback; executed when SmartConfig status changed;
|
||||
* @param uint8 log : 1, UART output logs; otherwise, UART only outputs the result.
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_smartconfig_start(sc_callback_t cb, ...);
|
||||
|
||||
/**
|
||||
* @brief Stop SmartConfig, free the buffer taken by esp_smartconfig_start.
|
||||
*
|
||||
* @attention Whether connect to AP succeed or not, this API should be called to free
|
||||
* memory taken by smartconfig_start.
|
||||
*
|
||||
* @param null
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_smartconfig_stop(void);
|
||||
|
||||
/**
|
||||
* @brief Set timeout of SmartConfig.
|
||||
*
|
||||
* @attention SmartConfig timeout start at SC_STATUS_FIND_CHANNEL, SmartConfig will
|
||||
* restart if timeout.
|
||||
*
|
||||
* @param uint8 time_s : range 15s~255s, offset:45s.
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_esptouch_set_timeout(uint8_t time_s);
|
||||
|
||||
/**
|
||||
* @brief Set protocol type of SmartConfig.
|
||||
*
|
||||
* @attention If users need to set the SmartConfig type, please set it before calling
|
||||
* esp_smartconfig_start.
|
||||
*
|
||||
* @param smartconfig_type_t type : AirKiss, ESP-TOUCH or both.
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_smartconfig_set_type(smartconfig_type_t type);
|
||||
|
||||
/**
|
||||
* @brief Set mode of SmartConfig. default normal mode.
|
||||
*
|
||||
* @attention If users need to set the SmartConfig mode, please set it before calling
|
||||
* esp_smartconfig_start. Different mode should match different APP(phone).
|
||||
*
|
||||
* @param bool enable : false-disable(default); true-enable;
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_smartconfig_fast_mode(bool enable);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -18,6 +18,7 @@
|
|||
#include <stdint.h>
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_deepsleep.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -62,21 +63,6 @@ void system_restore(void);
|
|||
*/
|
||||
void system_restart(void);
|
||||
|
||||
/**
|
||||
* @brief Set the chip to deep-sleep mode.
|
||||
*
|
||||
* The device will automatically wake up after the deep-sleep time set
|
||||
* by the users. Upon waking up, the device boots up from user_init.
|
||||
*
|
||||
* @attention The parameter time_in_us to be "uint64" is for further development.
|
||||
* Only the low 32 bits of parameter time_in_us are avalable now.
|
||||
*
|
||||
* @param uint64 time_in_us : deep-sleep time, only the low 32bits are avalable now. unit: microsecond
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
void system_deep_sleep(uint64_t time_in_us);
|
||||
|
||||
/**
|
||||
* @brief Get system time, unit: microsecond.
|
||||
*
|
||||
|
|
|
@ -15,10 +15,10 @@
|
|||
/* Notes:
|
||||
* 1. Put all task priority and stack size definition in this file
|
||||
* 2. If the task priority is less than 10, use ESP_TASK_PRIO_MIN + X style,
|
||||
* otherwise use ESP_TASK_PRIO_MIN - X style
|
||||
* 3. If this is a daemon task, the macro prifix is ESP_TASKD_, otherwise
|
||||
* otherwise use ESP_TASK_PRIO_MAX - X style
|
||||
* 3. If this is a daemon task, the macro prefix is ESP_TASKD_, otherwise
|
||||
* it's ESP_TASK_
|
||||
* 4. If the configMAX_PRIORITIES is modified, please make all prority are
|
||||
* 4. If the configMAX_PRIORITIES is modified, please make all priority are
|
||||
* greater than 0
|
||||
* 5. Make sure esp_task.h is consistent between wifi lib and idf
|
||||
*/
|
||||
|
@ -43,12 +43,17 @@
|
|||
#define ESP_TASK_WPS_PRIO (ESP_TASK_PRIO_MIN + 2)
|
||||
#define ESP_TASK_WPS_STACK 2048
|
||||
|
||||
/* Bt contoller Task */
|
||||
/* controller */
|
||||
#define ESP_TASK_BT_CONTROLLER_PRIO (ESP_TASK_PRIO_MAX - 1)
|
||||
#define ESP_TASK_BT_CONTROLLER_STACK 4096
|
||||
|
||||
/* idf task */
|
||||
#define ESP_TASKD_EVENT_PRIO (ESP_TASK_PRIO_MAX - 5)
|
||||
#define ESP_TASKD_EVENT_STACK CONFIG_SYSTEM_EVENT_TASK_STACK_SIZE
|
||||
#define ESP_TASK_WIFI_STARTUP_PRIO (ESP_TASK_PRIO_MAX - 7)
|
||||
#define ESP_TASK_WIFI_STARTUP_STACK 4096
|
||||
#define ESP_TASK_TCPIP_PRIO (ESP_TASK_PRIO_MAX - 7)
|
||||
#define ESP_TASK_TCPIP_STACK 2048
|
||||
#define ESP_TASK_MAIN_PRIO (ESP_TASK_PRIO_MIN + 1)
|
||||
#define ESP_TASK_MAIN_STACK CONFIG_MAIN_TASK_STACK_SIZE
|
||||
|
||||
#endif
|
||||
|
|
|
@ -59,113 +59,26 @@
|
|||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "rom/queue.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_wifi_types.h"
|
||||
#include "esp_event.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
WIFI_MODE_NULL = 0, /**< null mode */
|
||||
WIFI_MODE_STA, /**< WiFi station mode */
|
||||
WIFI_MODE_AP, /**< WiFi soft-AP mode */
|
||||
WIFI_MODE_APSTA, /**< WiFi station + soft-AP mode */
|
||||
WIFI_MODE_MAX
|
||||
} wifi_mode_t;
|
||||
|
||||
typedef enum {
|
||||
WIFI_IF_STA = 0, /**< ESP32 station interface */
|
||||
WIFI_IF_AP, /**< ESP32 soft-AP interface */
|
||||
WIFI_IF_MAX
|
||||
} wifi_interface_t;
|
||||
|
||||
typedef enum {
|
||||
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;
|
||||
|
||||
typedef enum {
|
||||
WIFI_AUTH_OPEN = 0, /**< authenticate mode : open */
|
||||
WIFI_AUTH_WEP, /**< authenticate mode : WEP */
|
||||
WIFI_AUTH_WPA_PSK, /**< authenticate mode : WPA_PSK */
|
||||
WIFI_AUTH_WPA2_PSK, /**< authenticate mode : WPA2_PSK */
|
||||
WIFI_AUTH_WPA_WPA2_PSK, /**< authenticate mode : WPA_WPA2_PSK */
|
||||
WIFI_AUTH_MAX
|
||||
} wifi_auth_mode_t;
|
||||
|
||||
enum {
|
||||
WIFI_REASON_UNSPECIFIED = 1,
|
||||
WIFI_REASON_AUTH_EXPIRE = 2,
|
||||
WIFI_REASON_AUTH_LEAVE = 3,
|
||||
WIFI_REASON_ASSOC_EXPIRE = 4,
|
||||
WIFI_REASON_ASSOC_TOOMANY = 5,
|
||||
WIFI_REASON_NOT_AUTHED = 6,
|
||||
WIFI_REASON_NOT_ASSOCED = 7,
|
||||
WIFI_REASON_ASSOC_LEAVE = 8,
|
||||
WIFI_REASON_ASSOC_NOT_AUTHED = 9,
|
||||
WIFI_REASON_DISASSOC_PWRCAP_BAD = 10,
|
||||
WIFI_REASON_DISASSOC_SUPCHAN_BAD = 11,
|
||||
WIFI_REASON_IE_INVALID = 13,
|
||||
WIFI_REASON_MIC_FAILURE = 14,
|
||||
WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT = 15,
|
||||
WIFI_REASON_GROUP_KEY_UPDATE_TIMEOUT = 16,
|
||||
WIFI_REASON_IE_IN_4WAY_DIFFERS = 17,
|
||||
WIFI_REASON_GROUP_CIPHER_INVALID = 18,
|
||||
WIFI_REASON_PAIRWISE_CIPHER_INVALID = 19,
|
||||
WIFI_REASON_AKMP_INVALID = 20,
|
||||
WIFI_REASON_UNSUPP_RSN_IE_VERSION = 21,
|
||||
WIFI_REASON_INVALID_RSN_IE_CAP = 22,
|
||||
WIFI_REASON_802_1X_AUTH_FAILED = 23,
|
||||
WIFI_REASON_CIPHER_SUITE_REJECTED = 24,
|
||||
|
||||
WIFI_REASON_BEACON_TIMEOUT = 200,
|
||||
WIFI_REASON_NO_AP_FOUND = 201,
|
||||
WIFI_REASON_AUTH_FAIL = 202,
|
||||
WIFI_REASON_ASSOC_FAIL = 203,
|
||||
WIFI_REASON_HANDSHAKE_TIMEOUT = 204,
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
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;
|
||||
|
||||
/**
|
||||
* @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);
|
||||
|
||||
esp_err_t esp_wifi_startup(wifi_startup_cb_t cb, void *ctx);
|
||||
|
||||
typedef struct {
|
||||
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 */
|
||||
system_event_handler_t event_handler; /**< WiFi event handler */
|
||||
} wifi_init_config_t;
|
||||
|
||||
|
||||
#define WIFI_INIT_CONFIG_DEFAULT() { \
|
||||
.event_handler = &esp_event_send, \
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Init WiFi
|
||||
* Alloc resource for WiFi driver, such as WiFi control structure, RX/TX buffer,
|
||||
|
@ -176,7 +89,6 @@ typedef struct {
|
|||
* 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
|
||||
*
|
||||
|
@ -288,13 +200,6 @@ esp_err_t esp_wifi_clear_fast_connect(void);
|
|||
*/
|
||||
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 */
|
||||
} wifi_scan_config_t;
|
||||
|
||||
/**
|
||||
* @brief Scan all available APs.
|
||||
*
|
||||
|
@ -332,15 +237,6 @@ esp_err_t esp_wifi_scan_stop(void);
|
|||
*/
|
||||
esp_err_t esp_wifi_get_ap_num(uint16_t *number);
|
||||
|
||||
typedef struct {
|
||||
uint8_t bssid[6]; /**< MAC address of AP */
|
||||
uint8_t ssid[32]; /**< SSID of AP */
|
||||
uint8_t primary; /**< channel of AP */
|
||||
wifi_second_chan_t second; /**< second channel of AP */
|
||||
int8_t rssi; /**< signal strength of AP */
|
||||
wifi_auth_mode_t authmode; /**< authmode of AP */
|
||||
} wifi_ap_list_t;
|
||||
|
||||
/**
|
||||
* @brief Get AP list found in last scan
|
||||
*
|
||||
|
@ -353,13 +249,6 @@ typedef struct {
|
|||
*/
|
||||
esp_err_t esp_wifi_get_ap_list(uint16_t *number, wifi_ap_list_t *ap_list);
|
||||
|
||||
typedef enum {
|
||||
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
|
||||
*
|
||||
|
@ -380,10 +269,6 @@ esp_err_t esp_wifi_set_ps(wifi_ps_type_t type);
|
|||
*/
|
||||
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
|
||||
|
||||
/**
|
||||
* @brief Set protocol type of specified interface
|
||||
* The default protocol is (WIFI_PROTOCOL_11B|WIFI_PROTOCOL_11G|WIFI_PROTOCOL_11N)
|
||||
|
@ -409,11 +294,6 @@ 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_bitmap);
|
||||
|
||||
typedef enum {
|
||||
WIFI_BW_HT20 = 0, /* Bandwidth is HT20 */
|
||||
WIFI_BW_HT40, /* Bandwidth is HT40 */
|
||||
} wifi_bandwidth_t;
|
||||
|
||||
/**
|
||||
* @brief Set the bandwidth of ESP32 specified interface
|
||||
*
|
||||
|
@ -542,45 +422,22 @@ 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
|
||||
* @param bool promiscuous : false - disable / true - enable
|
||||
*
|
||||
* @return ESP_OK : succeed
|
||||
* @return others : fail
|
||||
*/
|
||||
esp_err_t esp_wifi_set_promiscuous(uint8_t enable);
|
||||
esp_err_t esp_wifi_set_promiscuous(bool en);
|
||||
|
||||
/**
|
||||
* @brief Get the promiscuous mode.
|
||||
*
|
||||
* @param uint8 *enable : store the current status of promiscuous mode
|
||||
* @param bool *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 {
|
||||
char ssid[32]; /**< SSID of ESP32 soft-AP */
|
||||
char password[64]; /**< Password of ESP32 soft-AP */
|
||||
uint8_t ssid_len; /**< Length of SSID. If softap_config.ssid_len==0, check the SSID until there is a termination character; otherwise, set the SSID length according to softap_config.ssid_len. */
|
||||
uint8_t channel; /**< Channel of ESP32 soft-AP */
|
||||
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 ms */
|
||||
} wifi_ap_config_t;
|
||||
|
||||
typedef struct {
|
||||
char ssid[32]; /**< SSID of target AP*/
|
||||
char password[64]; /**< password of target AP*/
|
||||
bool bssid_set; /**< whether set MAC address of target AP or not. Generally, station_config.bssid_set needs to be 0; and it needs to be 1 only when users need to check the MAC address of the AP.*/
|
||||
uint8_t bssid[6]; /**< MAC address of target AP*/
|
||||
} wifi_sta_config_t;
|
||||
|
||||
typedef union {
|
||||
wifi_ap_config_t ap; /**< configuration of AP */
|
||||
wifi_sta_config_t sta; /**< configuration of STA */
|
||||
} wifi_config_t;
|
||||
esp_err_t esp_wifi_get_promiscuous(bool *en);
|
||||
|
||||
/**
|
||||
* @brief Set the configuration of the ESP32 STA or AP
|
||||
|
@ -609,11 +466,6 @@ esp_err_t esp_wifi_set_config(wifi_interface_t ifx, wifi_config_t *conf);
|
|||
*/
|
||||
esp_err_t esp_wifi_get_config(wifi_interface_t ifx, wifi_config_t *conf);
|
||||
|
||||
struct station_info {
|
||||
STAILQ_ENTRY(station_info) next;
|
||||
uint8_t bssid[6];
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Get STAs associated with soft-AP
|
||||
*
|
||||
|
@ -628,11 +480,6 @@ 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_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
|
||||
*
|
||||
|
@ -689,27 +536,6 @@ esp_err_t esp_wifi_set_auto_connect(bool en);
|
|||
*/
|
||||
esp_err_t esp_wifi_get_auto_connect(bool *en);
|
||||
|
||||
/**
|
||||
* @brief Vendor IE type
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
WIFI_VND_IE_TYPE_BEACON,
|
||||
WIFI_VND_IE_TYPE_PROBE_REQ,
|
||||
WIFI_VND_IE_TYPE_PROBE_RESP,
|
||||
WIFI_VND_IE_TYPE_ASSOC_REQ,
|
||||
WIFI_VND_IE_TYPE_ASSOC_RESP,
|
||||
} wifi_vendor_ie_type_t;
|
||||
|
||||
/**
|
||||
* @brief Vendor IE index
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
WIFI_VND_IE_ID_0,
|
||||
WIFI_VND_IE_ID_1,
|
||||
} wifi_vendor_ie_id_t;
|
||||
|
||||
/**
|
||||
* @brief Set vendor specific element
|
||||
*
|
||||
|
|
190
components/esp32/include/esp_wifi_types.h
Normal file
190
components/esp32/include/esp_wifi_types.h
Normal file
|
@ -0,0 +1,190 @@
|
|||
// 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_WIFI_TYPES_H__
|
||||
#define __ESP_WIFI_TYPES_H__
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "rom/queue.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_wifi_types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
WIFI_MODE_NULL = 0, /**< null mode */
|
||||
WIFI_MODE_STA, /**< WiFi station mode */
|
||||
WIFI_MODE_AP, /**< WiFi soft-AP mode */
|
||||
WIFI_MODE_APSTA, /**< WiFi station + soft-AP mode */
|
||||
WIFI_MODE_MAX
|
||||
} wifi_mode_t;
|
||||
|
||||
typedef enum {
|
||||
WIFI_IF_STA = 0, /**< ESP32 station interface */
|
||||
WIFI_IF_AP, /**< ESP32 soft-AP interface */
|
||||
WIFI_IF_MAX
|
||||
} wifi_interface_t;
|
||||
|
||||
typedef enum {
|
||||
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;
|
||||
|
||||
typedef enum {
|
||||
WIFI_AUTH_OPEN = 0, /**< authenticate mode : open */
|
||||
WIFI_AUTH_WEP, /**< authenticate mode : WEP */
|
||||
WIFI_AUTH_WPA_PSK, /**< authenticate mode : WPA_PSK */
|
||||
WIFI_AUTH_WPA2_PSK, /**< authenticate mode : WPA2_PSK */
|
||||
WIFI_AUTH_WPA_WPA2_PSK, /**< authenticate mode : WPA_WPA2_PSK */
|
||||
WIFI_AUTH_MAX
|
||||
} wifi_auth_mode_t;
|
||||
|
||||
enum {
|
||||
WIFI_REASON_UNSPECIFIED = 1,
|
||||
WIFI_REASON_AUTH_EXPIRE = 2,
|
||||
WIFI_REASON_AUTH_LEAVE = 3,
|
||||
WIFI_REASON_ASSOC_EXPIRE = 4,
|
||||
WIFI_REASON_ASSOC_TOOMANY = 5,
|
||||
WIFI_REASON_NOT_AUTHED = 6,
|
||||
WIFI_REASON_NOT_ASSOCED = 7,
|
||||
WIFI_REASON_ASSOC_LEAVE = 8,
|
||||
WIFI_REASON_ASSOC_NOT_AUTHED = 9,
|
||||
WIFI_REASON_DISASSOC_PWRCAP_BAD = 10,
|
||||
WIFI_REASON_DISASSOC_SUPCHAN_BAD = 11,
|
||||
WIFI_REASON_IE_INVALID = 13,
|
||||
WIFI_REASON_MIC_FAILURE = 14,
|
||||
WIFI_REASON_4WAY_HANDSHAKE_TIMEOUT = 15,
|
||||
WIFI_REASON_GROUP_KEY_UPDATE_TIMEOUT = 16,
|
||||
WIFI_REASON_IE_IN_4WAY_DIFFERS = 17,
|
||||
WIFI_REASON_GROUP_CIPHER_INVALID = 18,
|
||||
WIFI_REASON_PAIRWISE_CIPHER_INVALID = 19,
|
||||
WIFI_REASON_AKMP_INVALID = 20,
|
||||
WIFI_REASON_UNSUPP_RSN_IE_VERSION = 21,
|
||||
WIFI_REASON_INVALID_RSN_IE_CAP = 22,
|
||||
WIFI_REASON_802_1X_AUTH_FAILED = 23,
|
||||
WIFI_REASON_CIPHER_SUITE_REJECTED = 24,
|
||||
|
||||
WIFI_REASON_BEACON_TIMEOUT = 200,
|
||||
WIFI_REASON_NO_AP_FOUND = 201,
|
||||
WIFI_REASON_AUTH_FAIL = 202,
|
||||
WIFI_REASON_ASSOC_FAIL = 203,
|
||||
WIFI_REASON_HANDSHAKE_TIMEOUT = 204,
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
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 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 */
|
||||
} wifi_scan_config_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t bssid[6]; /**< MAC address of AP */
|
||||
uint8_t ssid[32]; /**< SSID of AP */
|
||||
uint8_t primary; /**< channel of AP */
|
||||
wifi_second_chan_t second; /**< second channel of AP */
|
||||
int8_t rssi; /**< signal strength of AP */
|
||||
wifi_auth_mode_t authmode; /**< authmode of AP */
|
||||
} wifi_ap_list_t;
|
||||
|
||||
typedef enum {
|
||||
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;
|
||||
|
||||
#define WIFI_PROTOCOL_11B 1
|
||||
#define WIFI_PROTOCOL_11G 2
|
||||
#define WIFI_PROTOCOL_11N 4
|
||||
|
||||
typedef enum {
|
||||
WIFI_BW_HT20 = 0, /* Bandwidth is HT20 */
|
||||
WIFI_BW_HT40, /* Bandwidth is HT40 */
|
||||
} wifi_bandwidth_t;
|
||||
|
||||
typedef struct {
|
||||
char ssid[32]; /**< SSID of ESP32 soft-AP */
|
||||
char password[64]; /**< Password of ESP32 soft-AP */
|
||||
uint8_t ssid_len; /**< Length of SSID. If softap_config.ssid_len==0, check the SSID until there is a termination character; otherwise, set the SSID length according to softap_config.ssid_len. */
|
||||
uint8_t channel; /**< Channel of ESP32 soft-AP */
|
||||
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 ms */
|
||||
} wifi_ap_config_t;
|
||||
|
||||
typedef struct {
|
||||
char ssid[32]; /**< SSID of target AP*/
|
||||
char password[64]; /**< password of target AP*/
|
||||
bool bssid_set; /**< whether set MAC address of target AP or not. Generally, station_config.bssid_set needs to be 0; and it needs to be 1 only when users need to check the MAC address of the AP.*/
|
||||
uint8_t bssid[6]; /**< MAC address of target AP*/
|
||||
} wifi_sta_config_t;
|
||||
|
||||
typedef union {
|
||||
wifi_ap_config_t ap; /**< configuration of AP */
|
||||
wifi_sta_config_t sta; /**< configuration of STA */
|
||||
} wifi_config_t;
|
||||
|
||||
struct station_info {
|
||||
STAILQ_ENTRY(station_info) next;
|
||||
uint8_t bssid[6];
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
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 Vendor IE type
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
WIFI_VND_IE_TYPE_BEACON,
|
||||
WIFI_VND_IE_TYPE_PROBE_REQ,
|
||||
WIFI_VND_IE_TYPE_PROBE_RESP,
|
||||
WIFI_VND_IE_TYPE_ASSOC_REQ,
|
||||
WIFI_VND_IE_TYPE_ASSOC_RESP,
|
||||
} wifi_vendor_ie_type_t;
|
||||
|
||||
/**
|
||||
* @brief Vendor IE index
|
||||
*
|
||||
*/
|
||||
typedef enum {
|
||||
WIFI_VND_IE_ID_0,
|
||||
WIFI_VND_IE_ID_1,
|
||||
} wifi_vendor_ie_id_t;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* __ESP_WIFI_TYPES_H__ */
|
|
@ -1,131 +0,0 @@
|
|||
// 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_WPS_H__
|
||||
#define __ESP_WPS_H__
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** \defgroup WiFi_APIs WiFi Related APIs
|
||||
* @brief WiFi APIs
|
||||
*/
|
||||
|
||||
/** @addtogroup WiFi_APIs
|
||||
* @{
|
||||
*/
|
||||
|
||||
/** \defgroup WPS_APIs WPS APIs
|
||||
* @brief ESP32 WPS APIs
|
||||
*
|
||||
* WPS can only be used when ESP32 station is enabled.
|
||||
*
|
||||
*/
|
||||
|
||||
/** @addtogroup WPS_APIs
|
||||
* @{
|
||||
*/
|
||||
|
||||
typedef enum wps_type {
|
||||
WPS_TYPE_DISABLE = 0,
|
||||
WPS_TYPE_PBC,
|
||||
WPS_TYPE_PIN,
|
||||
WPS_TYPE_DISPLAY,
|
||||
WPS_TYPE_MAX,
|
||||
} WPS_TYPE_t;
|
||||
|
||||
enum wps_cb_status {
|
||||
WPS_CB_ST_SUCCESS = 0, /**< WPS succeed */
|
||||
WPS_CB_ST_FAILED, /**< WPS fail */
|
||||
WPS_CB_ST_TIMEOUT, /**< WPS timeout, fail */
|
||||
WPS_CB_ST_WEP, /**< WPS failed because that WEP is not supported */
|
||||
WPS_CB_ST_SCAN_ERR, /**< can not find the target WPS AP */
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Enable Wi-Fi WPS function.
|
||||
*
|
||||
* @attention WPS can only be used when ESP32 station is enabled.
|
||||
*
|
||||
* @param WPS_TYPE_t wps_type : WPS type, so far only WPS_TYPE_PBC is supported
|
||||
*
|
||||
* @return true : succeed
|
||||
* @return false : fail
|
||||
*/
|
||||
bool wifi_wps_enable(WPS_TYPE_t wps_type);
|
||||
|
||||
/**
|
||||
* @brief Disable Wi-Fi WPS function and release resource it taken.
|
||||
*
|
||||
* @param null
|
||||
*
|
||||
* @return true : succeed
|
||||
* @return false : fail
|
||||
*/
|
||||
bool wifi_wps_disable(void);
|
||||
|
||||
/**
|
||||
* @brief WPS starts to work.
|
||||
*
|
||||
* @attention WPS can only be used when ESP32 station is enabled.
|
||||
*
|
||||
* @param null
|
||||
*
|
||||
* @return true : WPS starts to work successfully, but does not mean WPS succeed.
|
||||
* @return false : fail
|
||||
*/
|
||||
bool wifi_wps_start(void);
|
||||
|
||||
/**
|
||||
* @brief WPS callback.
|
||||
*
|
||||
* @param int status : status of WPS, enum wps_cb_status.
|
||||
* - If parameter status == WPS_CB_ST_SUCCESS in WPS callback, it means WPS got AP's
|
||||
* information, user can call wifi_wps_disable to disable WPS and release resource,
|
||||
* then call wifi_station_connect to connect to target AP.
|
||||
* - Otherwise, it means that WPS fail, user can create a timer to retry WPS by
|
||||
* wifi_wps_start after a while, or call wifi_wps_disable to disable WPS and release resource.
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
typedef void (*wps_st_cb_t)(int status);
|
||||
|
||||
/**
|
||||
* @brief Set WPS callback.
|
||||
*
|
||||
* @attention WPS can only be used when ESP32 station is enabled.
|
||||
*
|
||||
* @param wps_st_cb_t cb : callback.
|
||||
*
|
||||
* @return true : WPS starts to work successfully, but does not mean WPS succeed.
|
||||
* @return false : fail
|
||||
*/
|
||||
bool wifi_set_wps_cb(wps_st_cb_t cb);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __ESP_WPS_H__ */
|
|
@ -44,25 +44,25 @@ extern "C" {
|
|||
*************************************************************************************
|
||||
* 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
|
||||
* 0x3ff61000+SIZE_CP Slow 4096-SIZE_CP
|
||||
* 0x3ff62800 Slow 4096 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
|
||||
* RTC_CNTL_STORE0_REG
|
||||
* RTC_CNTL_STORE1_REG
|
||||
* RTC_CNTL_STORE2_REG
|
||||
* RTC_CNTL_STORE3_REG
|
||||
* RTC_CNTL_STORE4_REG Reserved
|
||||
* RTC_CNTL_STORE5_REG External Xtal Frequency
|
||||
* RTC_CNTL_STORE6_REG FAST_RTC_MEMORY_ENTRY
|
||||
* RTC_CNTL_STORE7_REG FAST_RTC_MEMORY_CRC
|
||||
*************************************************************************************
|
||||
*/
|
||||
#define RTC_ENTRY_ADDR RTC_STORE6
|
||||
#define RTC_MEMORY_CRC RTC_STORE7
|
||||
#define RTC_ENTRY_ADDR_REG RTC_CNTL_STORE6_REG
|
||||
#define RTC_MEMORY_CRC_REG RTC_CNTL_STORE7_REG
|
||||
|
||||
|
||||
typedef enum {
|
||||
|
@ -161,7 +161,7 @@ WAKEUP_REASON rtc_get_wakeup_cause(void);
|
|||
*
|
||||
* @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.
|
||||
* @param uint32_t crc_len : 0 - 0x7ff, 0 for 4 byte, 0x7ff for 0x2000 byte.
|
||||
*
|
||||
* @return uint32_t : CRC32 result
|
||||
*/
|
||||
|
|
|
@ -76,6 +76,6 @@ static inline void cpu_configure_region_protection()
|
|||
* This is a temporary function which will be replaced once dynamic
|
||||
* CPU frequency changing is implemented.
|
||||
*/
|
||||
void esp_set_cpu_freq();
|
||||
void esp_set_cpu_freq(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -280,6 +280,28 @@
|
|||
#define GPIO_SDIO_INT_H_V 0xFF
|
||||
#define GPIO_SDIO_INT_H_S 0
|
||||
|
||||
#define GPIO_REG(io_num) (GPIO_PIN0_REG + (io_num)*0x4)
|
||||
#define GPIO_PIN_INT_ENA 0x0000001F
|
||||
#define GPIO_PIN_INT_ENA_M ((GPIO_PIN_INT_ENA_V)<<(GPIO_PIN_INT_ENA_S))
|
||||
#define GPIO_PIN_INT_ENA_V 0x0000001F
|
||||
#define GPIO_PIN_INT_ENA_S 13
|
||||
#define GPIO_PIN_CONFIG 0x00000003
|
||||
#define GPIO_PIN_CONFIG_M ((GPIO_PIN_CONFIG_V)<<(GPIO_PIN_CONFIG_S))
|
||||
#define GPIO_PIN_CONFIG_V 0x00000003
|
||||
#define GPIO_PIN_CONFIG_S 11
|
||||
#define GPIO_PIN_WAKEUP_ENABLE (BIT(10))
|
||||
#define GPIO_PIN_WAKEUP_ENABLE_M (BIT(10))
|
||||
#define GPIO_PIN_WAKEUP_ENABLE_V 0x1
|
||||
#define GPIO_PIN_WAKEUP_ENABLE_S 10
|
||||
#define GPIO_PIN_INT_TYPE 0x00000007
|
||||
#define GPIO_PIN_INT_TYPE_M ((GPIO_PIN_INT_TYPE_V)<<(GPIO_PIN_INT_TYPE_S))
|
||||
#define GPIO_PIN_INT_TYPE_V 0x00000007
|
||||
#define GPIO_PIN_INT_TYPE_S 7
|
||||
#define GPIO_PIN_PAD_DRIVER (BIT(2))
|
||||
#define GPIO_PIN_PAD_DRIVER_M (BIT(2))
|
||||
#define GPIO_PIN_PAD_DRIVER_V 0x1
|
||||
#define GPIO_PIN_PAD_DRIVER_S 2
|
||||
|
||||
#define GPIO_PIN0_REG (DR_REG_GPIO_BASE + 0x0088)
|
||||
/* GPIO_PIN0_INT_ENA : R/W ;bitpos:[17:13] ;default: x ; */
|
||||
/*description: bit0: APP CPU interrupt enable bit1: APP CPU non-maskable interrupt
|
||||
|
|
|
@ -97,8 +97,8 @@ typedef volatile struct {
|
|||
} fifo_conf;
|
||||
union {
|
||||
struct {
|
||||
uint32_t data: 8; /*The register represent the byte data read from rx_fifo when use apb fifo access*/
|
||||
uint32_t reserved8: 24;
|
||||
uint8_t data; /*The register represent the byte data read from rx_fifo when use apb fifo access*/
|
||||
uint8_t reserved[3];
|
||||
};
|
||||
uint32_t val;
|
||||
} fifo_data;
|
||||
|
|
|
@ -40,6 +40,8 @@
|
|||
#define PIN_PULLDWN_EN(PIN_NAME) REG_SET_BIT(PIN_NAME, FUN_PD)
|
||||
#define PIN_FUNC_SELECT(PIN_NAME, FUNC) REG_SET_FIELD(PIN_NAME, MCU_SEL, FUNC)
|
||||
|
||||
#define PIN_FUNC_GPIO 2
|
||||
|
||||
#define PIN_CTRL (DR_REG_IO_MUX_BASE +0x00)
|
||||
#define CLK_OUT3 0xf
|
||||
#define CLK_OUT3_S 8
|
||||
|
@ -48,84 +50,17 @@
|
|||
#define CLK_OUT1 0xf
|
||||
#define CLK_OUT1_S 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO36_U (DR_REG_IO_MUX_BASE +0x04)
|
||||
#define FUNC_GPIO36_GPIO36 2
|
||||
#define FUNC_GPIO36_GPIO36_0 0
|
||||
#define PERIPHS_IO_MUX_GPIO0_U (DR_REG_IO_MUX_BASE +0x44)
|
||||
#define FUNC_GPIO0_EMAC_TX_CLK 5
|
||||
#define FUNC_GPIO0_GPIO0 2
|
||||
#define FUNC_GPIO0_CLK_OUT1 1
|
||||
#define FUNC_GPIO0_GPIO0_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO37_U (DR_REG_IO_MUX_BASE +0x08)
|
||||
#define FUNC_GPIO37_GPIO37 2
|
||||
#define FUNC_GPIO37_GPIO37_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO38_U (DR_REG_IO_MUX_BASE +0x0c)
|
||||
#define FUNC_GPIO38_GPIO38 2
|
||||
#define FUNC_GPIO38_GPIO38_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO39_U (DR_REG_IO_MUX_BASE +0x10)
|
||||
#define FUNC_GPIO39_GPIO39 2
|
||||
#define FUNC_GPIO39_GPIO39_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO34_U (DR_REG_IO_MUX_BASE +0x14)
|
||||
#define FUNC_GPIO34_GPIO34 2
|
||||
#define FUNC_GPIO34_GPIO34_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO35_U (DR_REG_IO_MUX_BASE +0x18)
|
||||
#define FUNC_GPIO35_GPIO35 2
|
||||
#define FUNC_GPIO35_GPIO35_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO32_U (DR_REG_IO_MUX_BASE +0x1c)
|
||||
#define FUNC_GPIO32_GPIO32 2
|
||||
#define FUNC_GPIO32_GPIO32_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO33_U (DR_REG_IO_MUX_BASE +0x20)
|
||||
#define FUNC_GPIO33_GPIO33 2
|
||||
#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_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
|
||||
|
||||
#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
|
||||
|
||||
#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_HS2_DATA3 3
|
||||
#define FUNC_MTCK_GPIO13 2
|
||||
#define FUNC_MTCK_HSPID 1
|
||||
#define FUNC_MTCK_MTCK 0
|
||||
|
||||
#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_HS2_CMD 3
|
||||
#define FUNC_MTDO_GPIO15 2
|
||||
#define FUNC_MTDO_HSPICS0 1
|
||||
#define FUNC_MTDO_MTDO 0
|
||||
#define PERIPHS_IO_MUX_U0TXD_U (DR_REG_IO_MUX_BASE +0x88)
|
||||
#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_GPIO2_U (DR_REG_IO_MUX_BASE +0x40)
|
||||
#define FUNC_GPIO2_SD_DATA0 4
|
||||
|
@ -134,11 +69,10 @@
|
|||
#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_GPIO0 2
|
||||
#define FUNC_GPIO0_CLK_OUT1 1
|
||||
#define FUNC_GPIO0_GPIO0_0 0
|
||||
#define PERIPHS_IO_MUX_U0RXD_U (DR_REG_IO_MUX_BASE +0x84)
|
||||
#define FUNC_U0RXD_GPIO3 2
|
||||
#define FUNC_U0RXD_CLK_OUT2 1
|
||||
#define FUNC_U0RXD_U0RXD 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO4_U (DR_REG_IO_MUX_BASE +0x48)
|
||||
#define FUNC_GPIO4_EMAC_TX_ER 5
|
||||
|
@ -148,40 +82,12 @@
|
|||
#define FUNC_GPIO4_HSPIHD 1
|
||||
#define FUNC_GPIO4_GPIO4_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO16_U (DR_REG_IO_MUX_BASE +0x4c)
|
||||
#define FUNC_GPIO16_EMAC_CLK_OUT 5
|
||||
#define FUNC_GPIO16_U2RXD 4
|
||||
#define FUNC_GPIO16_HS1_DATA4 3
|
||||
#define FUNC_GPIO16_GPIO16 2
|
||||
#define FUNC_GPIO16_GPIO16_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO17_U (DR_REG_IO_MUX_BASE +0x50)
|
||||
#define FUNC_GPIO17_EMAC_CLK_OUT_180 5
|
||||
#define FUNC_GPIO17_U2TXD 4
|
||||
#define FUNC_GPIO17_HS1_DATA5 3
|
||||
#define FUNC_GPIO17_GPIO17 2
|
||||
#define FUNC_GPIO17_GPIO17_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_SD_DATA2_U (DR_REG_IO_MUX_BASE +0x54)
|
||||
#define FUNC_SD_DATA2_U1RXD 4
|
||||
#define FUNC_SD_DATA2_HS1_DATA2 3
|
||||
#define FUNC_SD_DATA2_GPIO9 2
|
||||
#define FUNC_SD_DATA2_SPIHD 1
|
||||
#define FUNC_SD_DATA2_SD_DATA2 0
|
||||
|
||||
#define PERIPHS_IO_MUX_SD_DATA3_U (DR_REG_IO_MUX_BASE +0x58)
|
||||
#define FUNC_SD_DATA3_U1TXD 4
|
||||
#define FUNC_SD_DATA3_HS1_DATA3 3
|
||||
#define FUNC_SD_DATA3_GPIO10 2
|
||||
#define FUNC_SD_DATA3_SPIWP 1
|
||||
#define FUNC_SD_DATA3_SD_DATA3 0
|
||||
|
||||
#define PERIPHS_IO_MUX_SD_CMD_U (DR_REG_IO_MUX_BASE +0x5c)
|
||||
#define FUNC_SD_CMD_U1RTS 4
|
||||
#define FUNC_SD_CMD_HS1_CMD 3
|
||||
#define FUNC_SD_CMD_GPIO11 2
|
||||
#define FUNC_SD_CMD_SPICS0 1
|
||||
#define FUNC_SD_CMD_SD_CMD 0
|
||||
#define PERIPHS_IO_MUX_GPIO5_U (DR_REG_IO_MUX_BASE +0x6c)
|
||||
#define FUNC_GPIO5_EMAC_RX_CLK 5
|
||||
#define FUNC_GPIO5_HS1_DATA6 3
|
||||
#define FUNC_GPIO5_GPIO5 2
|
||||
#define FUNC_GPIO5_VSPICS0 1
|
||||
#define FUNC_GPIO5_GPIO5_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_SD_CLK_U (DR_REG_IO_MUX_BASE +0x60)
|
||||
#define FUNC_SD_CLK_U1CTS 4
|
||||
|
@ -204,12 +110,72 @@
|
|||
#define FUNC_SD_DATA1_SPID 1
|
||||
#define FUNC_SD_DATA1_SD_DATA1 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO5_U (DR_REG_IO_MUX_BASE +0x6c)
|
||||
#define FUNC_GPIO5_EMAC_RX_CLK 5
|
||||
#define FUNC_GPIO5_HS1_DATA6 3
|
||||
#define FUNC_GPIO5_GPIO5 2
|
||||
#define FUNC_GPIO5_VSPICS0 1
|
||||
#define FUNC_GPIO5_GPIO5_0 0
|
||||
#define PERIPHS_IO_MUX_SD_DATA2_U (DR_REG_IO_MUX_BASE +0x54)
|
||||
#define FUNC_SD_DATA2_U1RXD 4
|
||||
#define FUNC_SD_DATA2_HS1_DATA2 3
|
||||
#define FUNC_SD_DATA2_GPIO9 2
|
||||
#define FUNC_SD_DATA2_SPIHD 1
|
||||
#define FUNC_SD_DATA2_SD_DATA2 0
|
||||
|
||||
#define PERIPHS_IO_MUX_SD_DATA3_U (DR_REG_IO_MUX_BASE +0x58)
|
||||
#define FUNC_SD_DATA3_U1TXD 4
|
||||
#define FUNC_SD_DATA3_HS1_DATA3 3
|
||||
#define FUNC_SD_DATA3_GPIO10 2
|
||||
#define FUNC_SD_DATA3_SPIWP 1
|
||||
#define FUNC_SD_DATA3_SD_DATA3 0
|
||||
|
||||
#define PERIPHS_IO_MUX_SD_CMD_U (DR_REG_IO_MUX_BASE +0x5c)
|
||||
#define FUNC_SD_CMD_U1RTS 4
|
||||
#define FUNC_SD_CMD_HS1_CMD 3
|
||||
#define FUNC_SD_CMD_GPIO11 2
|
||||
#define FUNC_SD_CMD_SPICS0 1
|
||||
#define FUNC_SD_CMD_SD_CMD 0
|
||||
|
||||
#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
|
||||
|
||||
#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_HS2_DATA3 3
|
||||
#define FUNC_MTCK_GPIO13 2
|
||||
#define FUNC_MTCK_HSPID 1
|
||||
#define FUNC_MTCK_MTCK 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
|
||||
|
||||
#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_HS2_CMD 3
|
||||
#define FUNC_MTDO_GPIO15 2
|
||||
#define FUNC_MTDO_HSPICS0 1
|
||||
#define FUNC_MTDO_MTDO 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO16_U (DR_REG_IO_MUX_BASE +0x4c)
|
||||
#define FUNC_GPIO16_EMAC_CLK_OUT 5
|
||||
#define FUNC_GPIO16_U2RXD 4
|
||||
#define FUNC_GPIO16_HS1_DATA4 3
|
||||
#define FUNC_GPIO16_GPIO16 2
|
||||
#define FUNC_GPIO16_GPIO16_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO17_U (DR_REG_IO_MUX_BASE +0x50)
|
||||
#define FUNC_GPIO17_EMAC_CLK_OUT_180 5
|
||||
#define FUNC_GPIO17_U2TXD 4
|
||||
#define FUNC_GPIO17_HS1_DATA5 3
|
||||
#define FUNC_GPIO17_GPIO17 2
|
||||
#define FUNC_GPIO17_GPIO17_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO18_U (DR_REG_IO_MUX_BASE +0x70)
|
||||
#define FUNC_GPIO18_HS1_DATA7 3
|
||||
|
@ -241,17 +207,6 @@
|
|||
#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_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_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_HS1_STROBE 3
|
||||
#define FUNC_GPIO23_GPIO23 2
|
||||
|
@ -262,4 +217,51 @@
|
|||
#define FUNC_GPIO24_GPIO24 2
|
||||
#define FUNC_GPIO24_GPIO24_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_RX_DV 5
|
||||
#define FUNC_GPIO27_GPIO27 2
|
||||
#define FUNC_GPIO27_GPIO27_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO32_U (DR_REG_IO_MUX_BASE +0x1c)
|
||||
#define FUNC_GPIO32_GPIO32 2
|
||||
#define FUNC_GPIO32_GPIO32_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO33_U (DR_REG_IO_MUX_BASE +0x20)
|
||||
#define FUNC_GPIO33_GPIO33 2
|
||||
#define FUNC_GPIO33_GPIO33_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO34_U (DR_REG_IO_MUX_BASE +0x14)
|
||||
#define FUNC_GPIO34_GPIO34 2
|
||||
#define FUNC_GPIO34_GPIO34_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO35_U (DR_REG_IO_MUX_BASE +0x18)
|
||||
#define FUNC_GPIO35_GPIO35 2
|
||||
#define FUNC_GPIO35_GPIO35_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO36_U (DR_REG_IO_MUX_BASE +0x04)
|
||||
#define FUNC_GPIO36_GPIO36 2
|
||||
#define FUNC_GPIO36_GPIO36_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO37_U (DR_REG_IO_MUX_BASE +0x08)
|
||||
#define FUNC_GPIO37_GPIO37 2
|
||||
#define FUNC_GPIO37_GPIO37_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO38_U (DR_REG_IO_MUX_BASE +0x0c)
|
||||
#define FUNC_GPIO38_GPIO38 2
|
||||
#define FUNC_GPIO38_GPIO38_0 0
|
||||
|
||||
#define PERIPHS_IO_MUX_GPIO39_U (DR_REG_IO_MUX_BASE +0x10)
|
||||
#define FUNC_GPIO39_GPIO39 2
|
||||
#define FUNC_GPIO39_GPIO39_0 0
|
||||
|
||||
#endif /* _SOC_IO_MUX_REG_H_ */
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#ifndef _SOC_LEDC_STRUCT_H_
|
||||
#define _SOC_LEDC_STRUCT_H_
|
||||
typedef volatile struct {
|
||||
struct {
|
||||
struct {
|
||||
union {
|
||||
struct {
|
||||
|
@ -56,59 +57,19 @@ typedef volatile struct {
|
|||
};
|
||||
uint32_t val;
|
||||
} duty_rd;
|
||||
}high_speed_channel[8];
|
||||
} channel[8];
|
||||
} channel_group[2]; /*two channel groups : 0: high-speed channels; 1: low-speed channels*/
|
||||
struct {
|
||||
struct {
|
||||
union {
|
||||
struct {
|
||||
uint32_t timer_sel: 2; /*There are four low speed timers the two bits are used to select one of them for low speed channel. 2'b00: seletc lstimer0. 2'b01: select lstimer1. 2'b10: select lstimer2. 2'b11: select lstimer3.*/
|
||||
uint32_t sig_out_en: 1; /*This is the output enable control bit for low speed channel.*/
|
||||
uint32_t idle_lv: 1; /*This bit is used to control the output value when low speed channel is off.*/
|
||||
uint32_t para_up: 1; /*This bit is used to update register LEDC_LSCH0_HPOINT and LEDC_LSCH0_DUTY for low speed channel.*/
|
||||
uint32_t reserved5: 27;
|
||||
};
|
||||
uint32_t val;
|
||||
}conf0;
|
||||
union {
|
||||
struct {
|
||||
uint32_t hpoint: 20; /*The output value changes to high when lstimerx(x=[0 3]) selected by low speed channel has reached reg_hpoint_lsch0[19:0]*/
|
||||
uint32_t reserved20: 12;
|
||||
};
|
||||
uint32_t val;
|
||||
}hpoint;
|
||||
union {
|
||||
struct {
|
||||
uint32_t duty: 25; /*The register is used to control output duty. When lstimerx(x=[0 3]) choosed by low speed channel has reached reg_lpoint_lsch0 the output signal changes to low. reg_lpoint_lsch0=(reg_hpoint_lsch0[19:0]+reg_duty_lsch0[24:4]) (1) reg_lpoint_lsch0=(reg_hpoint_lsch0[19:0]+reg_duty_lsch0[24:4] +1) (2) The least four bits in this register represent the decimal part and determines when to choose (1) or (2)*/
|
||||
uint32_t reserved25: 7;
|
||||
};
|
||||
uint32_t val;
|
||||
}duty;
|
||||
union {
|
||||
struct {
|
||||
uint32_t duty_scale:10; /*This register controls the increase or decrease step scale for low speed channel.*/
|
||||
uint32_t duty_cycle:10; /*This register is used to increase or decrease the duty every reg_duty_cycle_lsch0 cycles for low speed channel.*/
|
||||
uint32_t duty_num: 10; /*This register is used to control the num of increased or decreased times for low speed channel6.*/
|
||||
uint32_t duty_inc: 1; /*This register is used to increase the duty of output signal or decrease the duty of output signal for low speed channel6.*/
|
||||
uint32_t duty_start: 1; /*When reg_duty_num_hsch1 reg_duty_cycle_hsch1 and reg_duty_scale_hsch1 has been configured. these register won't take effect until set reg_duty_start_hsch1. this bit is automatically cleared by hardware.*/
|
||||
};
|
||||
uint32_t val;
|
||||
}conf1;
|
||||
union {
|
||||
struct {
|
||||
uint32_t duty_read: 25; /*This register represents the current duty of the output signal for low speed channel.*/
|
||||
uint32_t reserved25: 7;
|
||||
};
|
||||
uint32_t val;
|
||||
}duty_r;
|
||||
}low_speed_channel[8];
|
||||
struct{
|
||||
union {
|
||||
struct {
|
||||
uint32_t timer_lim: 5; /*This register controls the range of the counter in high speed timer. the counter range is [0 2**reg_hstimer0_lim] the max bit width for counter is 20.*/
|
||||
uint32_t bit_num: 5; /*This register controls the range of the counter in high speed timer. the counter range is [0 2**reg_hstimer0_lim] the max bit width for counter is 20.*/
|
||||
uint32_t div_num: 18; /*This register is used to configure parameter for divider in high speed timer the least significant eight bits represent the decimal part.*/
|
||||
uint32_t pause: 1; /*This bit is used to pause the counter in high speed timer*/
|
||||
uint32_t rst: 1; /*This bit is used to reset high speed timer the counter will be 0 after reset.*/
|
||||
uint32_t tick_sel: 1; /*This bit is used to choose apb_clk or ref_tick for high speed timer. 1'b1:apb_clk 0:ref_tick*/
|
||||
uint32_t reserved26: 6;
|
||||
uint32_t low_speed_update: 1; /*This bit is only useful for low speed timer channels, reserved for high speed timers*/
|
||||
uint32_t reserved26: 5;
|
||||
};
|
||||
uint32_t val;
|
||||
} conf;
|
||||
|
@ -119,28 +80,8 @@ typedef volatile struct {
|
|||
};
|
||||
uint32_t val;
|
||||
} value;
|
||||
}high_speed_timer[4];
|
||||
struct{
|
||||
union {
|
||||
struct {
|
||||
uint32_t timer_lim: 5; /*This register controls the range of the counter in low speed timer. the counter range is [0 2**reg_lstimer0_lim] the max bit width for counter is 20.*/
|
||||
uint32_t div_num: 18; /*This register is used to configure parameter for divider in low speed timer the least significant eight bits represent the decimal part.*/
|
||||
uint32_t pause: 1; /*This bit is used to pause the counter in low speed timer.*/
|
||||
uint32_t rst: 1; /*This bit is used to reset low speed timer the counter will be 0 after reset.*/
|
||||
uint32_t tick_sel: 1; /*This bit is used to choose slow_clk or ref_tick for low speed timer. 1'b1:slow_clk 0:ref_tick*/
|
||||
uint32_t param_update: 1; /*Set this bit to update reg_div_num_lstime0 and reg_lstimer0_lim.*/
|
||||
uint32_t reserved27: 5;
|
||||
};
|
||||
uint32_t val;
|
||||
}conf;
|
||||
union {
|
||||
struct {
|
||||
uint32_t timer_cnt: 20; /*software can read this register to get the current counter value in low speed timer.*/
|
||||
uint32_t reserved20: 12;
|
||||
};
|
||||
uint32_t val;
|
||||
}value;
|
||||
}low_speed_timer[4];
|
||||
} timer[4];
|
||||
} timer_group[2]; /*two channel groups : 0: high-speed channels; 1: low-speed channels*/
|
||||
union {
|
||||
struct {
|
||||
uint32_t hstimer0_ovf: 1; /*The interrupt raw bit for high speed channel0 counter overflow.*/
|
||||
|
|
|
@ -225,4 +225,22 @@ typedef volatile struct {
|
|||
uint32_t date; /*This is the version register.*/
|
||||
} rmt_dev_t;
|
||||
extern rmt_dev_t RMT;
|
||||
|
||||
//Allow access to RMT memory using RMTMEM.chan[0].data[8]
|
||||
typedef volatile struct {
|
||||
struct {
|
||||
union {
|
||||
struct {
|
||||
uint32_t level1: 1;
|
||||
uint32_t duration1: 15;
|
||||
uint32_t level0: 1;
|
||||
uint32_t duration0: 15;
|
||||
|
||||
};
|
||||
uint32_t val;
|
||||
} data[64];
|
||||
} chan[8];
|
||||
} rmt_mem_t;
|
||||
extern rmt_mem_t RMTMEM;
|
||||
|
||||
#endif /* _SOC_RMT_STRUCT_H_ */
|
||||
|
|
|
@ -260,14 +260,14 @@
|
|||
/*************************************************************************************************************
|
||||
* Intr num Level Type PRO CPU usage APP CPU uasge
|
||||
* 0 1 extern level WMAC Reserved
|
||||
* 1 1 extern level BT/BLE Host Reserved
|
||||
* 1 1 extern level BT/BLE Host VHCI 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
|
||||
* 5 1 extern level BT Controller
|
||||
* 6 1 timer FreeRTOS Tick(L1) FreeRTOS Tick(L1)
|
||||
* 7 1 software Reserved Reserved
|
||||
* 8 1 extern level Reserved
|
||||
* 8 1 extern level BLE Controller
|
||||
* 9 1 extern level
|
||||
* 10 1 extern edge Internal Timer
|
||||
* 11 3 profiling
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
typedef volatile struct {
|
||||
union {
|
||||
struct {
|
||||
uint32_t rw_byte: 8; /*This register stores one byte data read by rx fifo.*/
|
||||
uint32_t reserved8: 24;
|
||||
uint8_t rw_byte; /*This register stores one byte data read by rx fifo.*/
|
||||
uint8_t reserved[3];
|
||||
};
|
||||
uint32_t val;
|
||||
} fifo;
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
/* THESE ARE THE VIRTUAL RUNTIME ADDRESSES */
|
||||
/* The load addresses are defined later using the AT statements. */
|
||||
MEMORY
|
||||
{
|
||||
/* All these values assume the flash cache is on, and have the blocks this uses subtracted from the length
|
||||
of the various regions. The 'data access port' dram/drom regions map to the same iram/irom regions but
|
||||
are connected to the data port of the CPU and eg allow bytewise access. */
|
||||
iram0_0_seg (RX) : org = 0x40080000, len = 0x20000 /* IRAM for PRO cpu. Not sure if happy with this, this is MMU area... */
|
||||
iram0_2_seg (RX) : org = 0x400D0018, len = 0x330000 /* Even though the segment name is iram, it is actually mapped to flash */
|
||||
dram0_0_seg (RW) : org = 0x3FFC0000, len = 0x40000 /* Shared RAM, minus rom bss/data/stack.*/
|
||||
drom0_0_seg (R) : org = 0x3F400010, len = 0x800000
|
||||
}
|
||||
|
||||
_heap_end = 0x40000000;
|
|
@ -1,14 +0,0 @@
|
|||
/* THESE ARE THE VIRTUAL RUNTIME ADDRESSES */
|
||||
/* The load addresses are defined later using the AT statements. */
|
||||
MEMORY
|
||||
{
|
||||
/* All these values assume the flash cache is on, and have the blocks this uses subtracted from the length
|
||||
of the various regions. The 'data access port' dram/drom regions map to the same iram/irom regions but
|
||||
are connected to the data port of the CPU and eg allow bytewise access. */
|
||||
iram0_0_seg (RX) : org = 0x40080000, len = 0x20000 /* IRAM for PRO cpu. Not sure if happy with this, this is MMU area... */
|
||||
iram0_2_seg (RX) : org = 0x400D0018, len = 0x330000 /* Even though the segment name is iram, it is actually mapped to flash */
|
||||
dram0_0_seg (RW) : org = 0x3FFC0000, len = 0x38000 /* Shared RAM, minus rom bss/data/stack.*/
|
||||
drom0_0_seg (R) : org = 0x3F400010, len = 0x800000
|
||||
}
|
||||
|
||||
_heap_end = 0x3FFF8000;
|
|
@ -1,5 +1,5 @@
|
|||
/* Default entry point: */
|
||||
ENTRY(call_user_start_cpu0);
|
||||
ENTRY(call_start_cpu0);
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
|
@ -153,4 +153,16 @@ SECTIONS
|
|||
_text_end = ABSOLUTE(.);
|
||||
_etext = .;
|
||||
} >iram0_2_seg
|
||||
|
||||
.rtc.text :
|
||||
{
|
||||
. = ALIGN(4);
|
||||
*(.rtc.literal .rtc.text)
|
||||
} >rtc_iram_seg
|
||||
|
||||
.rtc.data :
|
||||
{
|
||||
*(.rtc.data)
|
||||
*(.rtc.rodata)
|
||||
} > rtc_slow_seg
|
||||
}
|
||||
|
|
|
@ -1,14 +1,55 @@
|
|||
/* THESE ARE THE VIRTUAL RUNTIME ADDRESSES */
|
||||
/* The load addresses are defined later using the AT statements. */
|
||||
/* ESP32 Linker Script Memory Layout
|
||||
|
||||
This file describes the memory layout (memory blocks) as virtual
|
||||
memory addresses.
|
||||
|
||||
esp32.common.ld contains output sections to link compiler output
|
||||
into these memory blocks.
|
||||
|
||||
***
|
||||
|
||||
This linker script is passed through the C preprocessor to include
|
||||
configuration options.
|
||||
|
||||
Please use preprocessor features sparingly! Restrict
|
||||
to simple macros with numeric values, and/or #if/#endif blocks.
|
||||
*/
|
||||
#include "sdkconfig.h"
|
||||
|
||||
MEMORY
|
||||
{
|
||||
/* All these values assume the flash cache is on, and have the blocks this uses subtracted from the length
|
||||
of the various regions. The 'data access port' dram/drom regions map to the same iram/irom regions but
|
||||
are connected to the data port of the CPU and eg allow bytewise access. */
|
||||
iram0_0_seg (RX) : org = 0x40080000, len = 0x20000 /* IRAM for PRO cpu. Not sure if happy with this, this is MMU area... */
|
||||
iram0_2_seg (RX) : org = 0x400D0018, len = 0x330000 /* Even though the segment name is iram, it is actually mapped to flash */
|
||||
dram0_0_seg (RW) : org = 0x3FFB0000, len = 0x50000 /* Shared RAM, minus rom bss/data/stack.*/
|
||||
|
||||
/* IRAM for PRO cpu. Not sure if happy with this, this is MMU area... */
|
||||
iram0_0_seg (RX) : org = 0x40080000, len = 0x20000
|
||||
|
||||
/* Even though the segment name is iram, it is actually mapped to flash */
|
||||
iram0_2_seg (RX) : org = 0x400D0018, len = 0x330000
|
||||
|
||||
/* Shared data RAM, excluding memory reserved for ROM bss/data/stack.
|
||||
|
||||
Enabling Bluetooth & Trace Memory features in menuconfig will decrease
|
||||
the amount of RAM available.
|
||||
*/
|
||||
dram0_0_seg (RW) : org = 0x3FFB0000 + CONFIG_BT_RESERVE_DRAM,
|
||||
len = 0x50000 - CONFIG_TRACEMEM_RESERVE_DRAM - CONFIG_BT_RESERVE_DRAM
|
||||
|
||||
/* Flash mapped constant data */
|
||||
drom0_0_seg (R) : org = 0x3F400010, len = 0x800000
|
||||
|
||||
/* RTC fast memory (executable). Persists over deep sleep.
|
||||
*/
|
||||
rtc_iram_seg(RWX) : org = 0x400C0000, len = 0x2000
|
||||
|
||||
/* RTC slow memory (data accessible). Persists over deep sleep.
|
||||
|
||||
Start of RTC slow memory is reserved for ULP co-processor code + data, if enabled.
|
||||
*/
|
||||
rtc_slow_seg(RW) : org = 0x50000000 + CONFIG_ULP_COPROC_RESERVE_MEM,
|
||||
len = 0x1000 - CONFIG_ULP_COPROC_RESERVE_MEM
|
||||
}
|
||||
|
||||
_heap_end = 0x40000000;
|
||||
/* Heap ends at top of dram0_0_seg */
|
||||
_heap_end = 0x40000000 - CONFIG_TRACEMEM_RESERVE_DRAM;
|
||||
|
|
|
@ -9,6 +9,7 @@ PROVIDE ( UART1 = 0x3ff50000 );
|
|||
PROVIDE ( I2C0 = 0x3ff53000 );
|
||||
PROVIDE ( UHCI0 = 0x3ff54000 );
|
||||
PROVIDE ( RMT = 0x3ff56000 );
|
||||
PROVIDE ( RMTMEM = 0x3ff56800 );
|
||||
PROVIDE ( PCNT = 0x3ff57000 );
|
||||
PROVIDE ( LEDC = 0x3ff59000 );
|
||||
PROVIDE ( TIMERG0 = 0x3ff5F000 );
|
||||
|
|
|
@ -99,6 +99,10 @@ PROVIDE ( _data_end = 0x4000d5c8 );
|
|||
PROVIDE ( _data_end_btdm_rom = 0x4000d4f8 );
|
||||
PROVIDE ( _data_start = 0x4000d4f8 );
|
||||
PROVIDE ( _data_start_btdm_rom = 0x4000d4f4 );
|
||||
PROVIDE ( _data_start_btdm = 0x3ffae6e0);
|
||||
PROVIDE ( _data_end_btdm = 0x3ffaff10);
|
||||
PROVIDE ( _bss_start_btdm = 0x3ffb8000);
|
||||
PROVIDE ( _bss_end_btdm = 0x3ffbff70);
|
||||
PROVIDE ( _daylight = 0x3ffae0a4 );
|
||||
PROVIDE ( dbg_default_handler = 0x3ff97218 );
|
||||
PROVIDE ( dbg_state = 0x3ffb8d5d );
|
||||
|
@ -445,7 +449,6 @@ PROVIDE ( _lseek_r = 0x4000bd8c );
|
|||
PROVIDE ( __lshrdi3 = 0x4000c84c );
|
||||
PROVIDE ( __ltdf2 = 0x40063790 );
|
||||
PROVIDE ( __ltsf2 = 0x4006342c );
|
||||
PROVIDE ( main = 0x400076c4 );
|
||||
PROVIDE ( malloc = 0x4000bea0 );
|
||||
PROVIDE ( _malloc_r = 0x4000bbb4 );
|
||||
PROVIDE ( maxSecretKey_256 = 0x3ff97448 );
|
||||
|
@ -1378,6 +1381,7 @@ PROVIDE ( rom_iq_est_disable = 0x40005590 );
|
|||
PROVIDE ( rom_iq_est_enable = 0x40005514 );
|
||||
PROVIDE ( rom_linear_to_db = 0x40005f64 );
|
||||
PROVIDE ( rom_loopback_mode_en = 0x400030f8 );
|
||||
PROVIDE ( rom_main = 0x400076c4 );
|
||||
PROVIDE ( rom_meas_tone_pwr_db = 0x40006004 );
|
||||
PROVIDE ( rom_mhz2ieee = 0x4000404c );
|
||||
PROVIDE ( rom_noise_floor_auto_set = 0x40003bdc );
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
/* THESE ARE THE VIRTUAL RUNTIME ADDRESSES */
|
||||
/* The load addresses are defined later using the AT statements. */
|
||||
MEMORY
|
||||
{
|
||||
/* All these values assume the flash cache is on, and have the blocks this uses subtracted from the length
|
||||
of the various regions. The 'data access port' dram/drom regions map to the same iram/irom regions but
|
||||
are connected to the data port of the CPU and eg allow bytewise access. */
|
||||
iram0_0_seg (RX) : org = 0x40080000, len = 0x20000 /* IRAM for PRO cpu. Not sure if happy with this, this is MMU area... */
|
||||
iram0_2_seg (RX) : org = 0x400D0018, len = 0x330000 /* Even though the segment name is iram, it is actually mapped to flash */
|
||||
dram0_0_seg (RW) : org = 0x3FFB0000, len = 0x48000 /* Shared RAM, minus rom bss/data/stack.*/
|
||||
drom0_0_seg (R) : org = 0x3F400010, len = 0x800000
|
||||
}
|
||||
|
||||
_heap_end = 0x3FFF8000;
|
|
@ -1 +1 @@
|
|||
Subproject commit 3372298fe2ff517858bdc8c64f76540b9ac7d7d5
|
||||
Subproject commit a1e5f8b953c7934677ba7a6ed0a6dd2da0e6bd0f
|
|
@ -142,8 +142,12 @@ int _open_r(struct _reent *r, const char * path, int flags, int mode) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
void _exit(int __status) {
|
||||
abort();
|
||||
}
|
||||
|
||||
ssize_t _write_r(struct _reent *r, int fd, const void * data, size_t size) {
|
||||
const char* p = (const char*) data;
|
||||
const char *data_c = (const char *)data;
|
||||
if (fd == STDOUT_FILENO) {
|
||||
static _lock_t stdout_lock; /* lazily initialised */
|
||||
/* Even though newlib does stream locking on stdout, we need
|
||||
|
@ -160,14 +164,13 @@ ssize_t _write_r(struct _reent *r, int fd, const void * data, size_t size) {
|
|||
which aren't fully valid.)
|
||||
*/
|
||||
_lock_acquire_recursive(&stdout_lock);
|
||||
while(size--) {
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
#if CONFIG_NEWLIB_STDOUT_ADDCR
|
||||
if (*p=='\n') {
|
||||
if (data_c[i]=='\n') {
|
||||
uart_tx_one_char('\r');
|
||||
}
|
||||
#endif
|
||||
uart_tx_one_char(*p);
|
||||
++p;
|
||||
uart_tx_one_char(data_c[i]);
|
||||
}
|
||||
_lock_release_recursive(&stdout_lock);
|
||||
}
|
||||
|
|
|
@ -1,115 +0,0 @@
|
|||
// 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 <stdio.h>
|
||||
|
||||
#include "esp_err.h"
|
||||
#include "esp_wifi.h"
|
||||
#include "esp_event.h"
|
||||
#include "esp_task.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/semphr.h"
|
||||
|
||||
#if CONFIG_WIFI_ENABLED
|
||||
|
||||
static bool wifi_startup_flag = false;
|
||||
|
||||
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);\
|
||||
if ((ret) != __err) {\
|
||||
WIFI_DEBUG("%s %d %s ret=%d\n", __FUNCTION__, __LINE__, (info), __err);\
|
||||
return __err;\
|
||||
}\
|
||||
} while(0)
|
||||
|
||||
|
||||
|
||||
static void esp_wifi_task(void *pvParameters)
|
||||
{
|
||||
esp_err_t err;
|
||||
wifi_init_config_t cfg;
|
||||
cfg.event_q = (xQueueHandle)esp_event_get_handler();
|
||||
|
||||
do {
|
||||
err = esp_wifi_init(&cfg);
|
||||
if (err != ESP_OK) {
|
||||
WIFI_DEBUG("esp_wifi_init fail, ret=%d\n", err);
|
||||
break;
|
||||
}
|
||||
|
||||
if (startup_cb) {
|
||||
err = (*startup_cb)(startup_ctx);
|
||||
if (err != ESP_OK) {
|
||||
WIFI_DEBUG("startup_cb fail, ret=%d\n", err);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
err = esp_wifi_start();
|
||||
if (err != ESP_OK) {
|
||||
WIFI_DEBUG("esp_wifi_start fail, ret=%d\n", err);
|
||||
break;
|
||||
}
|
||||
|
||||
#if CONFIG_WIFI_AUTO_CONNECT
|
||||
wifi_mode_t mode;
|
||||
bool auto_connect;
|
||||
err = esp_wifi_get_mode(&mode);
|
||||
if (err != ESP_OK) {
|
||||
WIFI_DEBUG("esp_wifi_get_mode fail, ret=%d\n", err);
|
||||
}
|
||||
|
||||
err = esp_wifi_get_auto_connect(&auto_connect);
|
||||
if ((mode == WIFI_MODE_STA || mode == WIFI_MODE_APSTA) && auto_connect) {
|
||||
err = esp_wifi_connect();
|
||||
if (err != ESP_OK) {
|
||||
WIFI_DEBUG("esp_wifi_connect fail, ret=%d\n", err);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} while (0);
|
||||
|
||||
if (err != ESP_OK) {
|
||||
WIFI_DEBUG("wifi startup fail, deinit\n");
|
||||
esp_wifi_deinit();
|
||||
}
|
||||
|
||||
vTaskDelete(NULL);
|
||||
}
|
||||
|
||||
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", ESP_TASK_WIFI_STARTUP_STACK, NULL, ESP_TASK_WIFI_STARTUP_PRIO, NULL, 0);
|
||||
|
||||
return ESP_OK;
|
||||
}
|
||||
#endif
|
|
@ -16,7 +16,7 @@ ESPTOOLPY := $(PYTHON) $(ESPTOOLPY_SRC) --chip esp32
|
|||
ESPTOOLPY_SERIAL := $(ESPTOOLPY) --port $(ESPPORT) --baud $(ESPBAUD)
|
||||
|
||||
# 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)
|
||||
ESPTOOLPY_WRITE_FLASH=$(ESPTOOLPY_SERIAL) write_flash $(if $(CONFIG_ESPTOOLPY_COMPRESSED),-z) --flash_mode $(ESPFLASHMODE) --flash_freq $(ESPFLASHFREQ)
|
||||
|
||||
ESPTOOL_ALL_FLASH_ARGS += $(CONFIG_APP_OFFSET) $(APP_BIN)
|
||||
|
||||
|
@ -24,10 +24,11 @@ $(APP_BIN): $(APP_ELF) $(ESPTOOLPY_SRC)
|
|||
$(Q) $(ESPTOOLPY) elf2image --flash_mode $(ESPFLASHMODE) --flash_freq $(ESPFLASHFREQ) -o $@ $<
|
||||
|
||||
flash: all_binaries $(ESPTOOLPY_SRC)
|
||||
@echo "Flashing project app to $(CONFIG_APP_OFFSET)..."
|
||||
@echo "Flashing binaries to serial port $(ESPPORT) (app at offset $(CONFIG_APP_OFFSET))..."
|
||||
$(Q) $(ESPTOOLPY_WRITE_FLASH) $(ESPTOOL_ALL_FLASH_ARGS)
|
||||
|
||||
app-flash: $(APP_BIN) $(ESPTOOLPY_SRC)
|
||||
@echo "Flashing app to serial port $(ESPPORT), offset $(CONFIG_APP_OFFSET)..."
|
||||
$(Q) $(ESPTOOLPY_WRITE_FLASH) $(CONFIG_APP_OFFSET) $(APP_BIN)
|
||||
|
||||
$(eval $(call SubmoduleRequiredForFiles,$(ESPTOOLPY_SRC)))
|
||||
$(eval $(call SubmoduleCheck,$(ESPTOOLPY_SRC),$(COMPONENT_PATH)/esptool))
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 7c84dd433512bac80e4c01c569e42b4fe76646a7
|
||||
Subproject commit 197ba605fe0c05e16bf4c5ec07b726adc8d86abc
|
|
@ -10,6 +10,6 @@ COMPONENT_ADD_INCLUDEDIRS := port/include include/expat
|
|||
|
||||
COMPONENT_SRCDIRS := library port
|
||||
|
||||
CFLAGS += -Wno-error=address -Waddress -DHAVE_EXPAT_CONFIG_H
|
||||
CFLAGS += -Wno-unused-function -DHAVE_EXPAT_CONFIG_H
|
||||
|
||||
include $(IDF_PATH)/make/component_common.mk
|
||||
|
|
22
components/expat/expat.rst
Normal file
22
components/expat/expat.rst
Normal file
|
@ -0,0 +1,22 @@
|
|||
The Expat XML Parse Instruction
|
||||
=============================
|
||||
|
||||
Expat is an XML parser library written in C which be used for parse XML documents.
|
||||
|
||||
It is a stream-oriented parser in which an application registers handlers for things the parser might find in the XML document.
|
||||
|
||||
It can parse some larger files.
|
||||
|
||||
- Expat XML Parser support many different processor, but for the most part function you only need the following functions:
|
||||
|
||||
**XML_ParserCreate**: Create a new parser object
|
||||
|
||||
**XML_SetElementHandler**: Set handlers for start and end tags
|
||||
|
||||
**XML_SetCharacterDataHandler**: Set handler for text
|
||||
|
||||
**XML_Parse**: Pass a buffer full of document to the parser
|
||||
|
||||
More information about Expat library can be found on http://expat.sourceforge.net
|
||||
|
||||
An introductory article on using Expat is available on http://xml.com
|
|
@ -39,11 +39,19 @@ endchoice
|
|||
|
||||
config FREERTOS_HZ
|
||||
int "Tick rate (Hz)"
|
||||
range 1 10000
|
||||
range 1 1000
|
||||
default 100
|
||||
help
|
||||
Select the tick rate at which FreeRTOS does pre-emptive context switching.
|
||||
|
||||
config FREERTOS_ASSERT_ON_UNTESTED_FUNCTION
|
||||
bool "Halt when an SMP-untested function is called"
|
||||
default y
|
||||
help
|
||||
Some functions in FreeRTOS have not been thoroughly tested yet when moving to
|
||||
the SMP implementation of FreeRTOS. When this option is enabled, these fuctions
|
||||
will throw an assert().
|
||||
|
||||
choice FREERTOS_CHECK_STACKOVERFLOW
|
||||
prompt "Check for stack overflow"
|
||||
default FREERTOS_CHECK_STACKOVERFLOW_QUICK
|
||||
|
|
|
@ -143,6 +143,7 @@ BaseType_t xCoRoutineCreate( crCOROUTINE_CODE pxCoRoutineCode, UBaseType_t uxPri
|
|||
BaseType_t xReturn;
|
||||
CRCB_t *pxCoRoutine;
|
||||
|
||||
UNTESTED_FUNCTION(); //Actually, coroutines are entirely unsupported
|
||||
/* Allocate the memory that will store the co-routine control block. */
|
||||
pxCoRoutine = ( CRCB_t * ) pvPortMalloc( sizeof( CRCB_t ) );
|
||||
if( pxCoRoutine )
|
||||
|
|
|
@ -124,7 +124,6 @@ typedef struct xEventGroupDefinition
|
|||
|
||||
/* Again: one mux for all events. Maybe this can be made more granular. ToDo: look into that. -JD */
|
||||
static portMUX_TYPE xEventGroupMux = portMUX_INITIALIZER_UNLOCKED;
|
||||
static BaseType_t xMuxInitialized = pdFALSE;
|
||||
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
@ -145,12 +144,6 @@ EventGroupHandle_t xEventGroupCreate( void )
|
|||
{
|
||||
EventGroup_t *pxEventBits;
|
||||
|
||||
//Initialize mux, if needed
|
||||
if ( xMuxInitialized == pdFALSE ) {
|
||||
vPortCPUInitializeMutex( & xEventGroupMux );
|
||||
xMuxInitialized = pdTRUE;
|
||||
}
|
||||
|
||||
pxEventBits = pvPortMalloc( sizeof( EventGroup_t ) );
|
||||
if( pxEventBits != NULL )
|
||||
{
|
||||
|
|
|
@ -124,6 +124,16 @@
|
|||
abort(); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#if CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION
|
||||
#include <stdlib.h>
|
||||
#include "rom/ets_sys.h"
|
||||
#define UNTESTED_FUNCTION() { ets_printf("Untested FreeRTOS function %s\r\n", __FUNCTION__); configASSERT(false); } while(0)
|
||||
#else
|
||||
#define UNTESTED_FUNCTION()
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* def __ASSEMBLER__ */
|
||||
|
||||
|
||||
|
@ -265,5 +275,7 @@
|
|||
#define configXT_SIMULATOR 0
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* FREERTOS_CONFIG_H */
|
||||
|
||||
|
|
206
components/freertos/include/freertos/ringbuf.h
Normal file
206
components/freertos/include/freertos/ringbuf.h
Normal file
|
@ -0,0 +1,206 @@
|
|||
#ifndef FREERTOS_RINGBUF_H
|
||||
#define FREERTOS_RINGBUF_H
|
||||
|
||||
/*
|
||||
Header definitions for a FreeRTOS ringbuffer object
|
||||
|
||||
A ringbuffer instantiated by these functions essentially acts like a FreeRTOS queue, with the
|
||||
difference that it's strictly FIFO and with the main advantage that you can put in randomly-sized
|
||||
items. The capacity, accordingly, isn't measured in the amount of items, but the amount of memory
|
||||
that is used for storing the items. Dependent on the size of the items, more or less of them will
|
||||
fit in the ring buffer.
|
||||
|
||||
This ringbuffer tries to be efficient with memory: when inserting an item, the item data will
|
||||
be copied to the ringbuffer memory. When retrieving an item, however, a reference to ringbuffer
|
||||
memory will be returned. The returned memory is guaranteed to be 32-bit aligned and contiguous.
|
||||
The application can use this memory, but as long as it does, ringbuffer writes that would write
|
||||
to this bit of memory will block.
|
||||
|
||||
The requirement for items to be contiguous is slightly problematic when the only way to place
|
||||
the next item would involve a wraparound from the end to the beginning of the ringbuffer. This can
|
||||
be solved in two ways:
|
||||
- allow_split_items = pdTRUE: The insertion code will split the item in two items; one which fits
|
||||
in the space left at the end of the ringbuffer, one that contains the remaining data which is placed
|
||||
in the beginning. Two xRingbufferReceive calls will be needed to retrieve the data.
|
||||
- allow_split_items = pdFALSE: The insertion code will leave the room at the end of the ringbuffer
|
||||
unused and instead will put the entire item at the start of the ringbuffer, as soon as there is
|
||||
enough free space.
|
||||
|
||||
The maximum size of an item will be affected by this decision. When split items are allowed, it's
|
||||
acceptable to push items of (buffer_size)-16 bytes into the buffer. When it's not allowed, the
|
||||
maximum size is (buffer_size/2)-8 bytes.
|
||||
*/
|
||||
|
||||
//An opaque handle for a ringbuff object.
|
||||
typedef void * RingbufHandle_t;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Create a ring buffer
|
||||
*
|
||||
* @param buf_length : Length of circular buffer, in bytes. Each entry will take up its own length, plus a header
|
||||
* that at the moment is equal to sizeof(size_t).
|
||||
* @param allow_split_items : pdTRUE if it is acceptable that item data is inserted as two
|
||||
* items instead of one.
|
||||
*
|
||||
* @return A RingbufHandle_t handle to the created ringbuffer, or NULL in case of error.
|
||||
*/
|
||||
RingbufHandle_t xRingbufferCreate(size_t buf_length, BaseType_t allow_split_items);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Delete a ring buffer
|
||||
*
|
||||
* @param ringbuf - Ring buffer to delete
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void vRingbufferDelete(RingbufHandle_t ringbuf);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Get maximum size of an item that can be placed in the ring buffer
|
||||
*
|
||||
* @param ringbuf - Ring buffer to query
|
||||
*
|
||||
* @return Maximum size, in bytes, of an item that can be placed in a ring buffer.
|
||||
*/
|
||||
size_t xRingbufferGetMaxItemSize(RingbufHandle_t ringbuf);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Insert an item into the ring buffer
|
||||
*
|
||||
* @param ringbuf - Ring buffer to insert the item into
|
||||
* @param data - Pointer to data to insert. NULL is allowed if data_size is 0.
|
||||
* @param data_size - Size of data to insert. A value of 0 is allowed.
|
||||
* @param xTicksToWait - Ticks to wait for room in the ringbuffer.
|
||||
*
|
||||
* @return pdTRUE if succeeded, pdFALSE on time-out or when the buffer is larger
|
||||
* than indicated by xRingbufferGetMaxItemSize(ringbuf).
|
||||
*/
|
||||
BaseType_t xRingbufferSend(RingbufHandle_t ringbuf, void *data, size_t data_size, TickType_t ticks_to_wait);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Insert an item into the ring buffer from an ISR
|
||||
*
|
||||
* @param ringbuf - Ring buffer to insert the item into
|
||||
* @param data - Pointer to data to insert. NULL is allowed if data_size is 0.
|
||||
* @param data_size - Size of data to insert. A value of 0 is allowed.
|
||||
* @param higher_prio_task_awoken - Value pointed to will be set to pdTRUE if the push woke up a higher
|
||||
* priority task.
|
||||
*
|
||||
* @return pdTRUE if succeeded, pdFALSE when the ring buffer does not have space.
|
||||
*/
|
||||
BaseType_t xRingbufferSendFromISR(RingbufHandle_t ringbuf, void *data, size_t data_size, BaseType_t *higher_prio_task_awoken);
|
||||
|
||||
/**
|
||||
* @brief Retrieve an item from the ring buffer
|
||||
*
|
||||
* @param ringbuf - Ring buffer to retrieve the item from
|
||||
* @param item_size - Pointer to a variable to which the size of the retrieved item will be written.
|
||||
* @param xTicksToWait - Ticks to wait for items in the ringbuffer.
|
||||
*
|
||||
* @return Pointer to the retrieved item on success; *item_size filled with the length of the
|
||||
* item. NULL on timeout, *item_size is untouched in that case.
|
||||
*/
|
||||
void *xRingbufferReceive(RingbufHandle_t ringbuf, size_t *item_size, TickType_t ticks_to_wait);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Retrieve an item from the ring buffer from an ISR
|
||||
*
|
||||
* @param ringbuf - Ring buffer to retrieve the item from
|
||||
* @param item_size - Pointer to a variable to which the size of the retrieved item will be written.
|
||||
*
|
||||
* @return Pointer to the retrieved item on success; *item_size filled with the length of the
|
||||
* item. NULL when the ringbuffer is empty, *item_size is untouched in that case.
|
||||
*/
|
||||
void *xRingbufferReceiveFromISR(RingbufHandle_t ringbuf, size_t *item_size);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Return a previously-retrieved item to the ringbuffer
|
||||
*
|
||||
* @param ringbuf - Ring buffer the item was retrieved from
|
||||
* @param item - Item that was received earlier
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void vRingbufferReturnItem(RingbufHandle_t ringbuf, void *item);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @brief Return a previously-retrieved item to the ringbuffer from an ISR
|
||||
*
|
||||
* @param ringbuf - Ring buffer the item was retrieved from
|
||||
* @param item - Item that was received earlier
|
||||
* @param higher_prio_task_awoken - Value pointed to will be set to pdTRUE if the push woke up a higher
|
||||
* priority task.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void vRingbufferReturnItemFromISR(RingbufHandle_t ringbuf, void *item, BaseType_t *higher_prio_task_awoken);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Add the ringbuffer to a queue set. This specifically adds the semaphore that indicates
|
||||
* more space has become available in the ringbuffer.
|
||||
*
|
||||
* @param ringbuf - Ring buffer to add to the queue set
|
||||
* @param xQueueSet - Queue set to add the ringbuffer to
|
||||
*
|
||||
* @return pdTRUE on success, pdFALSE otherwise
|
||||
*/
|
||||
BaseType_t xRingbufferAddToQueueSetRead(RingbufHandle_t ringbuf, QueueSetHandle_t xQueueSet);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Add the ringbuffer to a queue set. This specifically adds the semaphore that indicates
|
||||
* something has been written into the ringbuffer.
|
||||
*
|
||||
* @param ringbuf - Ring buffer to add to the queue set
|
||||
* @param xQueueSet - Queue set to add the ringbuffer to
|
||||
*
|
||||
* @return pdTRUE on success, pdFALSE otherwise
|
||||
*/
|
||||
BaseType_t xRingbufferAddToQueueSetWrite(RingbufHandle_t ringbuf, QueueSetHandle_t xQueueSet);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Remove the ringbuffer from a queue set. This specifically removes the semaphore that indicates
|
||||
* more space has become available in the ringbuffer.
|
||||
*
|
||||
* @param ringbuf - Ring buffer to remove from the queue set
|
||||
* @param xQueueSet - Queue set to remove the ringbuffer from
|
||||
*
|
||||
* @return pdTRUE on success, pdFALSE otherwise
|
||||
*/
|
||||
BaseType_t xRingbufferRemoveFromQueueSetRead(RingbufHandle_t ringbuf, QueueSetHandle_t xQueueSet);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Remove the ringbuffer from a queue set. This specifically removes the semaphore that indicates
|
||||
* something has been written to the ringbuffer.
|
||||
*
|
||||
* @param ringbuf - Ring buffer to remove from the queue set
|
||||
* @param xQueueSet - Queue set to remove the ringbuffer from
|
||||
*
|
||||
* @return pdTRUE on success, pdFALSE otherwise
|
||||
*/
|
||||
BaseType_t xRingbufferRemoveFromQueueSetWrite(RingbufHandle_t ringbuf, QueueSetHandle_t xQueueSet);
|
||||
|
||||
|
||||
/**
|
||||
* @brief Debugging function to print the internal pointers in the ring buffer
|
||||
*
|
||||
* @param ringbuf - Ring buffer to show
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
void xRingbufferPrintInfo(RingbufHandle_t ringbuf);
|
||||
|
||||
|
||||
#endif
|
|
@ -2118,6 +2118,12 @@ BaseType_t xTaskPriorityDisinherit( TaskHandle_t const pxMutexHolder ) PRIVILEGE
|
|||
*/
|
||||
UBaseType_t uxTaskGetTaskNumber( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
||||
|
||||
|
||||
/*
|
||||
* Get the current core affinity of a task
|
||||
*/
|
||||
BaseType_t xTaskGetAffinity( TaskHandle_t xTask ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* Set the uxTaskNumber of the task referenced by the xTask parameter to
|
||||
* uxHandle.
|
||||
|
|
|
@ -81,7 +81,7 @@ int xPortGetCoreID();
|
|||
void __attribute__((weak)) vApplicationStackOverflowHook( TaskHandle_t xTask, signed char *pcTaskName ) {
|
||||
panicPutStr("***ERROR*** A stack overflow in task ");
|
||||
panicPutStr((char*)pcTaskName);
|
||||
panicPutStr("has been detected.\n");
|
||||
panicPutStr(" has been detected.\r\n");
|
||||
}
|
||||
|
||||
static const char *edesc[]={
|
||||
|
@ -160,7 +160,7 @@ void xt_unhandled_exception(XtExcFrame *frame) {
|
|||
panicPutStr("Guru Meditation Error of type ");
|
||||
x=regs[20];
|
||||
if (x<40) panicPutStr(edesc[x]); else panicPutStr("Unknown");
|
||||
panicPutStr(" occured on core ");
|
||||
panicPutStr(" occurred on core ");
|
||||
panicPutDec(xPortGetCoreID());
|
||||
if (inOCDMode()) {
|
||||
panicPutStr(" at pc=");
|
||||
|
|
|
@ -100,11 +100,6 @@ header files above, but not in this file, in order to generate the correct
|
|||
privileged Vs unprivileged linkage and placement. */
|
||||
#undef MPU_WRAPPERS_INCLUDED_FROM_API_FILE /*lint !e961 !e750. */
|
||||
|
||||
|
||||
/* Constants used with the xRxLock and xTxLock structure members. */
|
||||
#define queueUNLOCKED ( ( BaseType_t ) -1 )
|
||||
#define queueLOCKED_UNMODIFIED ( ( BaseType_t ) 0 )
|
||||
|
||||
/* When the Queue_t structure is used to represent a base queue its pcHead and
|
||||
pcTail members are used as pointers into the queue storage area. When the
|
||||
Queue_t structure is used to represent a mutex pcHead and pcTail pointers are
|
||||
|
@ -163,9 +158,6 @@ typedef struct QueueDefinition
|
|||
UBaseType_t uxLength; /*< The length of the queue defined as the number of items it will hold, not the number of bytes. */
|
||||
UBaseType_t uxItemSize; /*< The size of each items that the queue will hold. */
|
||||
|
||||
volatile BaseType_t xRxLock; /*< Stores the number of items received from the queue (removed from the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */
|
||||
volatile BaseType_t xTxLock; /*< Stores the number of items transmitted to the queue (added to the queue) while the queue was locked. Set to queueUNLOCKED when the queue is not locked. */
|
||||
|
||||
#if( ( configSUPPORT_STATIC_ALLOCATION == 1 ) && ( configSUPPORT_DYNAMIC_ALLOCATION == 1 ) )
|
||||
uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the memory used by the queue was statically allocated to ensure no attempt is made to free the memory. */
|
||||
#endif
|
||||
|
@ -216,15 +208,6 @@ typedef xQUEUE Queue_t;
|
|||
|
||||
#endif /* configQUEUE_REGISTRY_SIZE */
|
||||
|
||||
/*
|
||||
* Unlocks a queue locked by a call to prvLockQueue. Locking a queue does not
|
||||
* prevent an ISR from adding or removing items to the queue, but does prevent
|
||||
* an ISR from removing tasks from the queue event lists. If an ISR finds a
|
||||
* queue is locked it will instead increment the appropriate queue lock count
|
||||
* to indicate that a task may require unblocking. When the queue in unlocked
|
||||
* these lock counts are inspected, and the appropriate action taken.
|
||||
*/
|
||||
static void prvUnlockQueue( Queue_t * const pxQueue ) PRIVILEGED_FUNCTION;
|
||||
|
||||
/*
|
||||
* Uses a critical section to determine if there is any data in a queue.
|
||||
|
@ -274,27 +257,6 @@ static void prvInitialiseNewQueue( const UBaseType_t uxQueueLength, const UBaseT
|
|||
static void prvInitialiseMutex( Queue_t *pxNewQueue ) PRIVILEGED_FUNCTION;
|
||||
#endif
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
/*
|
||||
* Macro to mark a queue as locked. Locking a queue prevents an ISR from
|
||||
* accessing the queue event lists.
|
||||
*/
|
||||
#define prvLockQueue( pxQueue ) \
|
||||
taskENTER_CRITICAL(&pxQueue->mux); \
|
||||
{ \
|
||||
if( ( pxQueue )->xRxLock == queueUNLOCKED ) \
|
||||
{ \
|
||||
( pxQueue )->xRxLock = queueLOCKED_UNMODIFIED; \
|
||||
} \
|
||||
if( ( pxQueue )->xTxLock == queueUNLOCKED ) \
|
||||
{ \
|
||||
( pxQueue )->xTxLock = queueLOCKED_UNMODIFIED; \
|
||||
} \
|
||||
} \
|
||||
taskEXIT_CRITICAL(&pxQueue->mux)
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xQueueGenericReset( QueueHandle_t xQueue, BaseType_t xNewQueue )
|
||||
{
|
||||
Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
||||
|
@ -311,8 +273,6 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||
pxQueue->uxMessagesWaiting = ( UBaseType_t ) 0U;
|
||||
pxQueue->pcWriteTo = pxQueue->pcHead;
|
||||
pxQueue->u.pcReadFrom = pxQueue->pcHead + ( ( pxQueue->uxLength - ( UBaseType_t ) 1U ) * pxQueue->uxItemSize );
|
||||
pxQueue->xRxLock = queueUNLOCKED;
|
||||
pxQueue->xTxLock = queueUNLOCKED;
|
||||
|
||||
if( xNewQueue == pdFALSE )
|
||||
{
|
||||
|
@ -898,7 +858,6 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||
now the critical section has been exited. */
|
||||
|
||||
taskENTER_CRITICAL(&pxQueue->mux);
|
||||
// prvLockQueue( pxQueue );
|
||||
|
||||
/* Update the timeout state to see if it has expired yet. */
|
||||
if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
|
||||
|
@ -908,13 +867,6 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||
traceBLOCKING_ON_QUEUE_SEND( pxQueue );
|
||||
vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );
|
||||
|
||||
/* Unlocking the queue means queue events can effect the
|
||||
event list. It is possible that interrupts occurring now
|
||||
remove this task from the event list again - but as the
|
||||
scheduler is suspended the task will go onto the pending
|
||||
ready last instead of the actual ready list. */
|
||||
// prvUnlockQueue( pxQueue );
|
||||
|
||||
|
||||
/* Resuming the scheduler will move tasks from the pending
|
||||
ready list into the ready list - so it is feasible that this
|
||||
|
@ -927,14 +879,12 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||
else
|
||||
{
|
||||
/* Try again. */
|
||||
// prvUnlockQueue( pxQueue );
|
||||
taskEXIT_CRITICAL(&pxQueue->mux);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* The timeout has expired. */
|
||||
// prvUnlockQueue( pxQueue );
|
||||
taskEXIT_CRITICAL(&pxQueue->mux);
|
||||
|
||||
/* Return to the original privilege level before exiting the
|
||||
|
@ -1051,7 +1001,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||
|
||||
configASSERT( pxQueue );
|
||||
configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) );
|
||||
ets_printf("Not Supported: %s\n", __FUNCTION__);
|
||||
UNTESTED_FUNCTION();
|
||||
for( ;; )
|
||||
{
|
||||
taskENTER_CRITICAL();
|
||||
|
@ -1240,10 +1190,6 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||
disinheritance here or to clear the mutex holder TCB member. */
|
||||
( void ) prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
|
||||
|
||||
/* The event list is not altered if the queue is locked. This will
|
||||
be done when the queue is unlocked later. */
|
||||
if( pxQueue->xTxLock == queueUNLOCKED )
|
||||
{
|
||||
#if ( configUSE_QUEUE_SETS == 1 )
|
||||
{
|
||||
if( pxQueue->pxQueueSetContainer != NULL )
|
||||
|
@ -1323,14 +1269,6 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||
}
|
||||
}
|
||||
#endif /* configUSE_QUEUE_SETS */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Increment the lock count so the task that unlocks the queue
|
||||
knows that data was posted while it was locked. */
|
||||
++( pxQueue->xTxLock );
|
||||
}
|
||||
|
||||
xReturn = pdPASS;
|
||||
}
|
||||
else
|
||||
|
@ -1396,10 +1334,6 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||
|
||||
++( pxQueue->uxMessagesWaiting );
|
||||
|
||||
/* The event list is not altered if the queue is locked. This will
|
||||
be done when the queue is unlocked later. */
|
||||
if( pxQueue->xTxLock == queueUNLOCKED )
|
||||
{
|
||||
#if ( configUSE_QUEUE_SETS == 1 )
|
||||
{
|
||||
if( pxQueue->pxQueueSetContainer != NULL )
|
||||
|
@ -1479,13 +1413,6 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||
}
|
||||
}
|
||||
#endif /* configUSE_QUEUE_SETS */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Increment the lock count so the task that unlocks the queue
|
||||
knows that data was posted while it was locked. */
|
||||
++( pxQueue->xTxLock );
|
||||
}
|
||||
|
||||
xReturn = pdPASS;
|
||||
}
|
||||
|
@ -1636,7 +1563,6 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||
now the critical section has been exited. */
|
||||
|
||||
taskENTER_CRITICAL(&pxQueue->mux);
|
||||
// prvLockQueue( pxQueue );
|
||||
|
||||
/* Update the timeout state to see if it has expired yet. */
|
||||
if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdFALSE )
|
||||
|
@ -1659,20 +1585,17 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||
#endif
|
||||
|
||||
vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait );
|
||||
// prvUnlockQueue( pxQueue );
|
||||
taskEXIT_CRITICAL(&pxQueue->mux);
|
||||
portYIELD_WITHIN_API();
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Try again. */
|
||||
// prvUnlockQueue( pxQueue );
|
||||
taskEXIT_CRITICAL(&pxQueue->mux);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// prvUnlockQueue( pxQueue );
|
||||
taskEXIT_CRITICAL(&pxQueue->mux);
|
||||
traceQUEUE_RECEIVE_FAILED( pxQueue );
|
||||
return errQUEUE_EMPTY;
|
||||
|
@ -1717,12 +1640,6 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||
prvCopyDataFromQueue( pxQueue, pvBuffer );
|
||||
--( pxQueue->uxMessagesWaiting );
|
||||
|
||||
/* If the queue is locked the event list will not be modified.
|
||||
Instead update the lock count so the task that unlocks the queue
|
||||
will know that an ISR has removed data while the queue was
|
||||
locked. */
|
||||
if( pxQueue->xRxLock == queueUNLOCKED )
|
||||
{
|
||||
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
|
||||
{
|
||||
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
|
||||
|
@ -1747,13 +1664,6 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Increment the lock count so the task that unlocks the queue
|
||||
knows that data was removed while it was locked. */
|
||||
++( pxQueue->xRxLock );
|
||||
}
|
||||
|
||||
xReturn = pdPASS;
|
||||
}
|
||||
|
@ -2039,129 +1949,7 @@ static void prvCopyDataFromQueue( Queue_t * const pxQueue, void * const pvBuffer
|
|||
( void ) memcpy( ( void * ) pvBuffer, ( void * ) pxQueue->u.pcReadFrom, ( size_t ) pxQueue->uxItemSize ); /*lint !e961 !e418 MISRA exception as the casts are only redundant for some ports. Also previous logic ensures a null pointer can only be passed to memcpy() when the count is 0. */
|
||||
}
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static void prvUnlockQueue( Queue_t * const pxQueue )
|
||||
{
|
||||
/* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. */
|
||||
|
||||
/* The lock counts contains the number of extra data items placed or
|
||||
removed from the queue while the queue was locked. When a queue is
|
||||
locked items can be added or removed, but the event lists cannot be
|
||||
updated. */
|
||||
taskENTER_CRITICAL(&pxQueue->mux);
|
||||
{
|
||||
/* See if data was added to the queue while it was locked. */
|
||||
while( pxQueue->xTxLock > queueLOCKED_UNMODIFIED )
|
||||
{
|
||||
/* Data was posted while the queue was locked. Are any tasks
|
||||
blocked waiting for data to become available? */
|
||||
#if ( configUSE_QUEUE_SETS == 1 )
|
||||
{
|
||||
if( pxQueue->pxQueueSetContainer != NULL )
|
||||
{
|
||||
if( prvNotifyQueueSetContainer( pxQueue, queueSEND_TO_BACK ) == pdTRUE )
|
||||
{
|
||||
/* The queue is a member of a queue set, and posting to
|
||||
the queue set caused a higher priority task to unblock.
|
||||
A context switch is required. */
|
||||
taskEXIT_CRITICAL(&pxQueue->mux); //ToDo: Is aquire/release needed around any of the bTaskMissedYield calls?
|
||||
vTaskMissedYield();
|
||||
taskENTER_CRITICAL(&pxQueue->mux);
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Tasks that are removed from the event list will get added to
|
||||
the pending ready list as the scheduler is still suspended. */
|
||||
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
|
||||
{
|
||||
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
|
||||
{
|
||||
/* The task waiting has a higher priority so record that a
|
||||
context switch is required. */
|
||||
taskEXIT_CRITICAL(&pxQueue->mux);
|
||||
vTaskMissedYield();
|
||||
taskENTER_CRITICAL(&pxQueue->mux);
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else /* configUSE_QUEUE_SETS */
|
||||
{
|
||||
/* Tasks that are removed from the event list will get added to
|
||||
the pending ready list as the scheduler is still suspended. */
|
||||
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
|
||||
{
|
||||
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
|
||||
{
|
||||
/* The task waiting has a higher priority so record that a
|
||||
context switch is required. */
|
||||
taskEXIT_CRITICAL(&pxQueue->mux);
|
||||
vTaskMissedYield();
|
||||
taskENTER_CRITICAL(&pxQueue->mux);
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* configUSE_QUEUE_SETS */
|
||||
|
||||
--( pxQueue->xTxLock );
|
||||
}
|
||||
|
||||
pxQueue->xTxLock = queueUNLOCKED;
|
||||
}
|
||||
taskEXIT_CRITICAL(&pxQueue->mux);
|
||||
|
||||
/* Do the same for the Rx lock. */
|
||||
taskENTER_CRITICAL(&pxQueue->mux);
|
||||
{
|
||||
while( pxQueue->xRxLock > queueLOCKED_UNMODIFIED )
|
||||
{
|
||||
if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
|
||||
{
|
||||
if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
|
||||
{
|
||||
taskEXIT_CRITICAL(&pxQueue->mux);
|
||||
vTaskMissedYield();
|
||||
taskENTER_CRITICAL(&pxQueue->mux);
|
||||
}
|
||||
else
|
||||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
|
||||
--( pxQueue->xRxLock );
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pxQueue->xRxLock = queueUNLOCKED;
|
||||
}
|
||||
taskEXIT_CRITICAL(&pxQueue->mux);
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
static BaseType_t prvIsQueueEmpty( Queue_t *pxQueue )
|
||||
|
@ -2254,6 +2042,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||
BaseType_t xReturn;
|
||||
Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
||||
|
||||
UNTESTED_FUNCTION();
|
||||
/* If the queue is already full we may have to block. A critical section
|
||||
is required to prevent an interrupt removing something from the queue
|
||||
between the check to see if the queue is full and blocking on the queue. */
|
||||
|
@ -2528,6 +2317,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||
{
|
||||
UBaseType_t ux;
|
||||
|
||||
UNTESTED_FUNCTION();
|
||||
/* See if there is an empty space in the registry. A NULL name denotes
|
||||
a free slot. */
|
||||
for( ux = ( UBaseType_t ) 0U; ux < ( UBaseType_t ) configQUEUE_REGISTRY_SIZE; ux++ )
|
||||
|
@ -2595,10 +2385,8 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||
/* Only do anything if there are no messages in the queue. This function
|
||||
will not actually cause the task to block, just place it on a blocked
|
||||
list. It will not block until the scheduler is unlocked - at which
|
||||
time a yield will be performed. If an item is added to the queue while
|
||||
the queue is locked, and the calling task blocks on the queue, then the
|
||||
calling task will be immediately unblocked when the queue is unlocked. */
|
||||
// prvLockQueue( pxQueue );
|
||||
time a yield will be performed. */
|
||||
taskENTER_CRITICAL(&pxQueue->mux);
|
||||
if( pxQueue->uxMessagesWaiting == ( UBaseType_t ) 0U )
|
||||
{
|
||||
/* There is nothing in the queue, block for the specified period. */
|
||||
|
@ -2608,7 +2396,7 @@ Queue_t * const pxQueue = ( Queue_t * ) xQueue;
|
|||
{
|
||||
mtCOVERAGE_TEST_MARKER();
|
||||
}
|
||||
// prvUnlockQueue( pxQueue );
|
||||
taskEXIT_CRITICAL(&pxQueue->mux);
|
||||
}
|
||||
|
||||
#endif /* configUSE_TIMERS */
|
||||
|
|
474
components/freertos/ringbuf.c
Normal file
474
components/freertos/ringbuf.c
Normal file
|
@ -0,0 +1,474 @@
|
|||
// 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 "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "freertos/queue.h"
|
||||
#include "freertos/xtensa_api.h"
|
||||
#include "freertos/ringbuf.h"
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
typedef enum {
|
||||
flag_allowsplit = 1,
|
||||
} rbflag_t;
|
||||
|
||||
typedef enum {
|
||||
iflag_free = 1, //Buffer is not read and given back by application, free to overwrite
|
||||
iflag_dummydata = 2, //Data from here to end of ringbuffer is dummy. Restart reading at start of ringbuffer.
|
||||
} itemflag_t;
|
||||
|
||||
|
||||
//The ringbuffer structure
|
||||
typedef struct {
|
||||
SemaphoreHandle_t free_space_sem; //Binary semaphore, wakes up writing threads when there's more free space
|
||||
SemaphoreHandle_t items_buffered_sem; //Binary semaphore, indicates there are new packets in the circular buffer. See remark.
|
||||
size_t size; //Size of the data storage
|
||||
uint8_t *write_ptr; //Pointer where the next item is written
|
||||
uint8_t *read_ptr; //Pointer from where the next item is read
|
||||
uint8_t *free_ptr; //Pointer to the last block that hasn't been given back to the ringbuffer yet
|
||||
uint8_t *data; //Data storage
|
||||
portMUX_TYPE mux; //Spinlock for actual data/ptr/struct modification
|
||||
rbflag_t flags;
|
||||
} ringbuf_t;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Remark: A counting semaphore for items_buffered_sem would be more logical, but counting semaphores in
|
||||
FreeRTOS need a maximum count, and allocate more memory the larger the maximum count is. Here, we
|
||||
would need to set the maximum to the maximum amount of times a null-byte unit firs in the buffer,
|
||||
which is quite high and so would waste a fair amount of memory.
|
||||
*/
|
||||
|
||||
|
||||
//The header prepended to each ringbuffer entry. Size is assumed to be a multiple of 32bits.
|
||||
typedef struct {
|
||||
size_t len;
|
||||
itemflag_t flags;
|
||||
} buf_entry_hdr_t;
|
||||
|
||||
|
||||
//Calculate space free in the buffer
|
||||
static int ringbufferFreeMem(ringbuf_t *rb)
|
||||
{
|
||||
int free_size = rb->free_ptr-rb->write_ptr;
|
||||
if (free_size <= 0) free_size += rb->size;
|
||||
//Reserve one byte. If we do not do this and the entire buffer is filled, we get a situation
|
||||
//where read_ptr == free_ptr, messing up the next calculation.
|
||||
return free_size-1;
|
||||
}
|
||||
|
||||
//Copies a single item to the ring buffer. Assumes there is space in the ringbuffer and
|
||||
//the ringbuffer is locked. Increases write_ptr to the next item. Returns pdTRUE on
|
||||
//success, pdFALSE if it can't make the item fit and the calling routine needs to retry
|
||||
//later or fail.
|
||||
//This function by itself is not threadsafe, always call from within a muxed section.
|
||||
static BaseType_t copyItemToRingbuf(ringbuf_t *rb, uint8_t *buffer, size_t buffer_size)
|
||||
{
|
||||
size_t rbuffer_size=(buffer_size+3)&~3; //Payload length, rounded to next 32-bit value
|
||||
configASSERT(((int)rb->write_ptr&3)==0); //write_ptr needs to be 32-bit aligned
|
||||
configASSERT(rb->write_ptr-(rb->data+rb->size) >= sizeof(buf_entry_hdr_t)); //need to have at least the size
|
||||
//of a header to the end of the ringbuff
|
||||
size_t rem_len=(rb->data + rb->size) - rb->write_ptr; //length remaining until end of ringbuffer
|
||||
|
||||
//See if we have enough contiguous space to write the buffer.
|
||||
if (rem_len < rbuffer_size + sizeof(buf_entry_hdr_t)) {
|
||||
//The buffer can't be contiguously written to the ringbuffer, but needs special handling. Do
|
||||
//that depending on how the ringbuffer is configured.
|
||||
//The code here is also expected to check if the buffer, mangled in whatever way is implemented,
|
||||
//will still fit, and return pdFALSE if that is not the case.
|
||||
if (rb->flags & flag_allowsplit) {
|
||||
//Buffer plus header is not going to fit in the room from wr_pos to the end of the
|
||||
//ringbuffer... we need to split the write in two.
|
||||
//First, see if this will fit at all.
|
||||
if (ringbufferFreeMem(rb) < (sizeof(buf_entry_hdr_t)*2)+rbuffer_size) {
|
||||
//Will not fit.
|
||||
return pdFALSE;
|
||||
}
|
||||
//Because the code at the end of the function makes sure we always have
|
||||
//room for a header, this should never assert.
|
||||
configASSERT(rem_len>=sizeof(buf_entry_hdr_t));
|
||||
//Okay, it should fit. Write everything.
|
||||
//First, place bit of buffer that does fit. Write header first...
|
||||
buf_entry_hdr_t *hdr=(buf_entry_hdr_t *)rb->write_ptr;
|
||||
hdr->flags=0;
|
||||
hdr->len=rem_len-sizeof(buf_entry_hdr_t);
|
||||
rb->write_ptr+=sizeof(buf_entry_hdr_t);
|
||||
rem_len-=sizeof(buf_entry_hdr_t);
|
||||
if (rem_len!=0) {
|
||||
//..then write the data bit that fits.
|
||||
memcpy(rb->write_ptr, buffer, rem_len);
|
||||
//Update vars so the code later on will write the rest of the data.
|
||||
buffer+=rem_len;
|
||||
rbuffer_size-=rem_len;
|
||||
buffer_size-=rem_len;
|
||||
} else {
|
||||
//Huh, only the header fit. Mark as dummy so the receive function doesn't receive
|
||||
//an useless zero-byte packet.
|
||||
hdr->flags|=iflag_dummydata;
|
||||
}
|
||||
rb->write_ptr=rb->data;
|
||||
} else {
|
||||
//Buffer plus header is not going to fit in the room from wr_pos to the end of the
|
||||
//ringbuffer... but we're not allowed to split the buffer. We need to fill the
|
||||
//rest of the ringbuffer with a dummy item so we can place the data at the _start_ of
|
||||
//the ringbuffer..
|
||||
//First, find out if we actually have enough space at the start of the ringbuffer to
|
||||
//make this work (Again, we need 4 bytes extra because otherwise read_ptr==free_ptr)
|
||||
if (rb->free_ptr-rb->data < rbuffer_size+sizeof(buf_entry_hdr_t)+4) {
|
||||
//Will not fit.
|
||||
return pdFALSE;
|
||||
}
|
||||
//If the read buffer hasn't wrapped around yet, there's no way this will work either.
|
||||
if (rb->free_ptr > rb->write_ptr) {
|
||||
//No luck.
|
||||
return pdFALSE;
|
||||
}
|
||||
|
||||
//Okay, it will fit. Mark the rest of the ringbuffer space with a dummy packet.
|
||||
buf_entry_hdr_t *hdr=(buf_entry_hdr_t *)rb->write_ptr;
|
||||
hdr->flags=iflag_dummydata;
|
||||
//Reset the write pointer to the start of the ringbuffer so the code later on can
|
||||
//happily write the data.
|
||||
rb->write_ptr=rb->data;
|
||||
}
|
||||
} else {
|
||||
//No special handling needed. Checking if it's gonna fit probably still is a good idea.
|
||||
if (ringbufferFreeMem(rb) < sizeof(buf_entry_hdr_t)+rbuffer_size) {
|
||||
//Buffer is not going to fit, period.
|
||||
return pdFALSE;
|
||||
}
|
||||
}
|
||||
|
||||
//If we are here, the buffer is guaranteed to fit in the space starting at the write pointer.
|
||||
buf_entry_hdr_t *hdr=(buf_entry_hdr_t *)rb->write_ptr;
|
||||
hdr->len=buffer_size;
|
||||
hdr->flags=0;
|
||||
rb->write_ptr+=sizeof(buf_entry_hdr_t);
|
||||
memcpy(rb->write_ptr, buffer, buffer_size);
|
||||
rb->write_ptr+=rbuffer_size;
|
||||
|
||||
//The buffer will wrap around if we don't have room for a header anymore.
|
||||
if ((rb->data+rb->size)-rb->write_ptr < sizeof(buf_entry_hdr_t)) {
|
||||
//'Forward' the write buffer until we are at the start of the ringbuffer.
|
||||
//The read pointer will always be at the start of a full header, which cannot
|
||||
//exist at the point of the current write pointer, so there's no chance of overtaking
|
||||
//that.
|
||||
rb->write_ptr=rb->data;
|
||||
}
|
||||
return pdTRUE;
|
||||
}
|
||||
|
||||
//Retrieves a pointer to the data of the next item, or NULL if this is not possible.
|
||||
//This function by itself is not threadsafe, always call from within a muxed section.
|
||||
static uint8_t *getItemFromRingbuf(ringbuf_t *rb, size_t *length)
|
||||
{
|
||||
uint8_t *ret;
|
||||
configASSERT(((int)rb->read_ptr&3)==0);
|
||||
if (rb->read_ptr == rb->write_ptr) {
|
||||
//No data available.
|
||||
return NULL;
|
||||
}
|
||||
//The item written at the point of the read pointer may be a dummy item.
|
||||
//We need to skip past it first, if that's the case.
|
||||
buf_entry_hdr_t *hdr=(buf_entry_hdr_t *)rb->read_ptr;
|
||||
configASSERT((hdr->len < rb->size) || (hdr->flags & iflag_dummydata));
|
||||
if (hdr->flags & iflag_dummydata) {
|
||||
//Hdr is dummy data. Reset to start of ringbuffer.
|
||||
rb->read_ptr=rb->data;
|
||||
//Get real header
|
||||
hdr=(buf_entry_hdr_t *)rb->read_ptr;
|
||||
configASSERT(hdr->len < rb->size);
|
||||
//No need to re-check if the ringbuffer is empty: the write routine will
|
||||
//always write a dummy item plus the real data item in one go, so now we must
|
||||
//be at the real data item by definition.
|
||||
}
|
||||
//Okay, pass the data back.
|
||||
ret=rb->read_ptr+sizeof(buf_entry_hdr_t);
|
||||
*length=hdr->len;
|
||||
//...and move the read pointer past the data.
|
||||
rb->read_ptr+=sizeof(buf_entry_hdr_t)+((hdr->len+3)&~3);
|
||||
//The buffer will wrap around if we don't have room for a header anymore.
|
||||
if ((rb->data + rb->size) - rb->read_ptr < sizeof(buf_entry_hdr_t)) {
|
||||
rb->read_ptr=rb->data;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
//Returns an item to the ringbuffer. Will mark the item as free, and will see if the free pointer
|
||||
//can be increase.
|
||||
//This function by itself is not threadsafe, always call from within a muxed section.
|
||||
static void returnItemToRingbuf(ringbuf_t *rb, void *item) {
|
||||
uint8_t *data=(uint8_t*)item;
|
||||
configASSERT(((int)rb->free_ptr&3)==0);
|
||||
configASSERT(data >= rb->data);
|
||||
configASSERT(data < rb->data+rb->size);
|
||||
//Grab the buffer entry that preceeds the buffer
|
||||
buf_entry_hdr_t *hdr=(buf_entry_hdr_t*)(data-sizeof(buf_entry_hdr_t));
|
||||
configASSERT(hdr->len < rb->size);
|
||||
configASSERT((hdr->flags & iflag_dummydata)==0);
|
||||
configASSERT((hdr->flags & iflag_free)==0);
|
||||
//Mark the buffer as free.
|
||||
hdr->flags|=iflag_free;
|
||||
|
||||
//Do a cleanup pass.
|
||||
hdr=(buf_entry_hdr_t *)rb->free_ptr;
|
||||
//basically forward free_ptr until we run into either a block that is still in use or the write pointer.
|
||||
while (((hdr->flags & iflag_free) || (hdr->flags & iflag_dummydata)) && rb->free_ptr != rb->write_ptr) {
|
||||
if (hdr->flags & iflag_dummydata) {
|
||||
//Rest is dummy data. Reset to start of ringbuffer.
|
||||
rb->free_ptr=rb->data;
|
||||
} else {
|
||||
//Skip past item
|
||||
size_t len=(hdr->len+3)&~3;
|
||||
rb->free_ptr+=len+sizeof(buf_entry_hdr_t);
|
||||
configASSERT(rb->free_ptr<=rb->data+rb->size);
|
||||
}
|
||||
//The buffer will wrap around if we don't have room for a header anymore.
|
||||
if ((rb->data+rb->size)-rb->free_ptr < sizeof(buf_entry_hdr_t)) {
|
||||
rb->free_ptr=rb->data;
|
||||
}
|
||||
//Next header
|
||||
hdr=(buf_entry_hdr_t *)rb->free_ptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void xRingbufferPrintInfo(RingbufHandle_t ringbuf)
|
||||
{
|
||||
ringbuf_t *rb=(ringbuf_t *)ringbuf;
|
||||
configASSERT(rb);
|
||||
ets_printf("Rb size %d free %d rptr %d freeptr %d wptr %d\n",
|
||||
rb->size, ringbufferFreeMem(rb), rb->read_ptr-rb->data, rb->free_ptr-rb->data, rb->write_ptr-rb->data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
RingbufHandle_t xRingbufferCreate(size_t buf_length, BaseType_t allow_split_items)
|
||||
{
|
||||
ringbuf_t *rb = malloc(sizeof(ringbuf_t));
|
||||
if (rb==NULL) goto err;
|
||||
memset(rb, 0, sizeof(ringbuf_t));
|
||||
rb->data = malloc(buf_length);
|
||||
if (rb->data == NULL) goto err;
|
||||
rb->size = buf_length;
|
||||
rb->free_ptr = rb->data;
|
||||
rb->read_ptr = rb->data;
|
||||
rb->write_ptr = rb->data;
|
||||
rb->free_space_sem = xSemaphoreCreateBinary();
|
||||
rb->items_buffered_sem = xSemaphoreCreateBinary();
|
||||
rb->flags=0;
|
||||
if (allow_split_items) rb->flags|=flag_allowsplit;
|
||||
if (rb->free_space_sem == NULL || rb->items_buffered_sem == NULL) goto err;
|
||||
vPortCPUInitializeMutex(&rb->mux);
|
||||
return (RingbufHandle_t)rb;
|
||||
|
||||
err:
|
||||
//Some error has happened. Free/destroy all allocated things and return NULL.
|
||||
if (rb) {
|
||||
free(rb->data);
|
||||
if (rb->free_space_sem) vSemaphoreDelete(rb->free_space_sem);
|
||||
if (rb->items_buffered_sem) vSemaphoreDelete(rb->items_buffered_sem);
|
||||
}
|
||||
free(rb);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void vRingbufferDelete(RingbufHandle_t ringbuf) {
|
||||
ringbuf_t *rb=(ringbuf_t *)ringbuf;
|
||||
if (rb) {
|
||||
free(rb->data);
|
||||
if (rb->free_space_sem) vSemaphoreDelete(rb->free_space_sem);
|
||||
if (rb->items_buffered_sem) vSemaphoreDelete(rb->items_buffered_sem);
|
||||
}
|
||||
free(rb);
|
||||
}
|
||||
|
||||
size_t xRingbufferGetMaxItemSize(RingbufHandle_t ringbuf)
|
||||
{
|
||||
ringbuf_t *rb=(ringbuf_t *)ringbuf;
|
||||
configASSERT(rb);
|
||||
//In both cases, we return 4 bytes less than what we actually can have. If the ringbuffer is
|
||||
//indeed entirely filled, read_ptr==free_ptr, which throws off the free space calculation.
|
||||
if (rb->flags & flag_allowsplit) {
|
||||
//Worst case, we need to split an item into two, which means two headers of overhead.
|
||||
return rb->size-(sizeof(buf_entry_hdr_t)*2)-4;
|
||||
} else {
|
||||
//Worst case, we have the write ptr in such a position that we are lacking four bytes of free
|
||||
//memory to put an item into the rest of the memory. If this happens, we have to dummy-fill
|
||||
//(item_data-4) bytes of buffer, then we only have (size-(item_data-4) bytes left to fill
|
||||
//with the real item. (item size being header+data)
|
||||
return (rb->size/2)-sizeof(buf_entry_hdr_t)-4;
|
||||
}
|
||||
}
|
||||
|
||||
BaseType_t xRingbufferSend(RingbufHandle_t ringbuf, void *data, size_t dataSize, TickType_t ticks_to_wait)
|
||||
{
|
||||
ringbuf_t *rb=(ringbuf_t *)ringbuf;
|
||||
size_t needed_size=dataSize+sizeof(buf_entry_hdr_t);
|
||||
BaseType_t done=pdFALSE;
|
||||
portTickType ticks_end=xTaskGetTickCount() + ticks_to_wait;
|
||||
|
||||
configASSERT(rb);
|
||||
|
||||
if (dataSize > xRingbufferGetMaxItemSize(ringbuf)) {
|
||||
//Data will never ever fit in the queue.
|
||||
return pdFALSE;
|
||||
}
|
||||
|
||||
while (!done) {
|
||||
//Check if there is enough room in the buffer. If not, wait until there is.
|
||||
do {
|
||||
if (ringbufferFreeMem(rb) < needed_size) {
|
||||
//Data does not fit yet. Wait until the free_space_sem is given, then re-evaluate.
|
||||
|
||||
BaseType_t r = xSemaphoreTake(rb->free_space_sem, ticks_to_wait);
|
||||
if (r == pdFALSE) {
|
||||
//Timeout.
|
||||
return pdFALSE;
|
||||
}
|
||||
//Adjust ticks_to_wait; we may have waited less than that and in the case the free memory still is not enough,
|
||||
//we will need to wait some more.
|
||||
ticks_to_wait = ticks_end - xTaskGetTickCount();
|
||||
}
|
||||
} while (ringbufferFreeMem(rb) < needed_size && ticks_to_wait>=0);
|
||||
|
||||
//Lock the mux in order to make sure no one else is messing with the ringbuffer and do the copy.
|
||||
portENTER_CRITICAL(&rb->mux);
|
||||
//Another thread may have been able to sneak its write first. Check again now we locked the ringbuff, and retry
|
||||
//everything if this is the case. Otherwise, we can write and are done.
|
||||
done=copyItemToRingbuf(rb, data, dataSize);
|
||||
portEXIT_CRITICAL(&rb->mux);
|
||||
}
|
||||
xSemaphoreGive(rb->items_buffered_sem);
|
||||
return pdTRUE;
|
||||
}
|
||||
|
||||
|
||||
BaseType_t xRingbufferSendFromISR(RingbufHandle_t ringbuf, void *data, size_t dataSize, BaseType_t *higher_prio_task_awoken)
|
||||
{
|
||||
ringbuf_t *rb=(ringbuf_t *)ringbuf;
|
||||
BaseType_t write_succeeded;
|
||||
configASSERT(rb);
|
||||
size_t needed_size=dataSize+sizeof(buf_entry_hdr_t);
|
||||
portENTER_CRITICAL_ISR(&rb->mux);
|
||||
if (needed_size>ringbufferFreeMem(rb)) {
|
||||
//Does not fit in the remaining space in the ringbuffer.
|
||||
write_succeeded=pdFALSE;
|
||||
} else {
|
||||
copyItemToRingbuf(rb, data, dataSize);
|
||||
write_succeeded=pdTRUE;
|
||||
}
|
||||
portEXIT_CRITICAL_ISR(&rb->mux);
|
||||
if (write_succeeded) {
|
||||
xSemaphoreGiveFromISR(rb->items_buffered_sem, higher_prio_task_awoken);
|
||||
}
|
||||
return write_succeeded;
|
||||
}
|
||||
|
||||
|
||||
void *xRingbufferReceive(RingbufHandle_t ringbuf, size_t *item_size, TickType_t ticks_to_wait)
|
||||
{
|
||||
ringbuf_t *rb=(ringbuf_t *)ringbuf;
|
||||
uint8_t *itemData;
|
||||
BaseType_t done=pdFALSE;
|
||||
configASSERT(rb);
|
||||
while(!done) {
|
||||
//See if there's any data available. If not, wait until there is.
|
||||
while (rb->read_ptr == rb->write_ptr) {
|
||||
BaseType_t r=xSemaphoreTake(rb->items_buffered_sem, ticks_to_wait);
|
||||
if (r == pdFALSE) {
|
||||
//Timeout.
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
//Okay, we seem to have data in the buffer. Grab the mux and copy it out if it's still there.
|
||||
portENTER_CRITICAL(&rb->mux);
|
||||
itemData=getItemFromRingbuf(rb, item_size);
|
||||
portEXIT_CRITICAL(&rb->mux);
|
||||
if (itemData) {
|
||||
//We managed to get an item.
|
||||
done=pdTRUE;
|
||||
}
|
||||
}
|
||||
return (void*)itemData;
|
||||
}
|
||||
|
||||
|
||||
void *xRingbufferReceiveFromISR(RingbufHandle_t ringbuf, size_t *item_size)
|
||||
{
|
||||
ringbuf_t *rb=(ringbuf_t *)ringbuf;
|
||||
uint8_t *itemData;
|
||||
configASSERT(rb);
|
||||
portENTER_CRITICAL_ISR(&rb->mux);
|
||||
itemData=getItemFromRingbuf(rb, item_size);
|
||||
portEXIT_CRITICAL_ISR(&rb->mux);
|
||||
return (void*)itemData;
|
||||
}
|
||||
|
||||
|
||||
void vRingbufferReturnItem(RingbufHandle_t ringbuf, void *item)
|
||||
{
|
||||
ringbuf_t *rb=(ringbuf_t *)ringbuf;
|
||||
portENTER_CRITICAL_ISR(&rb->mux);
|
||||
returnItemToRingbuf(rb, item);
|
||||
portEXIT_CRITICAL_ISR(&rb->mux);
|
||||
xSemaphoreGive(rb->free_space_sem);
|
||||
}
|
||||
|
||||
|
||||
void vRingbufferReturnItemFromISR(RingbufHandle_t ringbuf, void *item, BaseType_t *higher_prio_task_awoken)
|
||||
{
|
||||
ringbuf_t *rb=(ringbuf_t *)ringbuf;
|
||||
portENTER_CRITICAL_ISR(&rb->mux);
|
||||
returnItemToRingbuf(rb, item);
|
||||
portEXIT_CRITICAL_ISR(&rb->mux);
|
||||
xSemaphoreGiveFromISR(rb->free_space_sem, higher_prio_task_awoken);
|
||||
}
|
||||
|
||||
|
||||
BaseType_t xRingbufferAddToQueueSetRead(RingbufHandle_t ringbuf, QueueSetHandle_t xQueueSet)
|
||||
{
|
||||
ringbuf_t *rb=(ringbuf_t *)ringbuf;
|
||||
configASSERT(rb);
|
||||
return xQueueAddToSet(rb->items_buffered_sem, xQueueSet);
|
||||
}
|
||||
|
||||
|
||||
BaseType_t xRingbufferAddToQueueSetWrite(RingbufHandle_t ringbuf, QueueSetHandle_t xQueueSet)
|
||||
{
|
||||
ringbuf_t *rb=(ringbuf_t *)ringbuf;
|
||||
configASSERT(rb);
|
||||
return xQueueAddToSet(rb->free_space_sem, xQueueSet);
|
||||
}
|
||||
|
||||
|
||||
BaseType_t xRingbufferRemoveFromQueueSetRead(RingbufHandle_t ringbuf, QueueSetHandle_t xQueueSet)
|
||||
{
|
||||
ringbuf_t *rb=(ringbuf_t *)ringbuf;
|
||||
configASSERT(rb);
|
||||
return xQueueRemoveFromSet(rb->items_buffered_sem, xQueueSet);
|
||||
}
|
||||
|
||||
BaseType_t xRingbufferRemoveFromQueueSetWrite(RingbufHandle_t ringbuf, QueueSetHandle_t xQueueSet)
|
||||
{
|
||||
ringbuf_t *rb=(ringbuf_t *)ringbuf;
|
||||
configASSERT(rb);
|
||||
return xQueueRemoveFromSet(rb->free_space_sem, xQueueSet);
|
||||
}
|
||||
|
|
@ -130,6 +130,7 @@ functions but without including stdio.h here. */
|
|||
|
||||
|
||||
|
||||
|
||||
/* Value that can be assigned to the eNotifyState member of the TCB. */
|
||||
typedef enum
|
||||
{
|
||||
|
@ -177,7 +178,7 @@ typedef struct tskTaskControlBlock
|
|||
StackType_t *pxStack; /*< Points to the start of the stack. */
|
||||
char pcTaskName[ configMAX_TASK_NAME_LEN ];/*< Descriptive name given to the task when created. Facilitates debugging only. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */
|
||||
BaseType_t xCoreID; /*< Core this task is pinned to */
|
||||
|
||||
/* If this moves around (other than pcTaskName size changes), please change the define in xtensa_vectors.S as well. */
|
||||
#if ( portSTACK_GROWTH > 0 )
|
||||
StackType_t *pxEndOfStack; /*< Points to the end of the stack on architectures where the stack grows up from low memory. */
|
||||
#endif
|
||||
|
@ -301,9 +302,7 @@ when the scheduler is unsuspended. The pending ready list itself can only be
|
|||
accessed from a critical section. */
|
||||
PRIVILEGED_DATA static volatile UBaseType_t uxSchedulerSuspended[ portNUM_PROCESSORS ] = { ( UBaseType_t ) pdFALSE };
|
||||
|
||||
/* Muxes used in the task code */
|
||||
PRIVILEGED_DATA static portBASE_TYPE xMutexesInitialised = pdFALSE;
|
||||
/* For now, we use just one mux for all the critical sections. ToDo: give evrything a bit more granularity;
|
||||
/* For now, we use just one mux for all the critical sections. ToDo: give everything a bit more granularity;
|
||||
that could improve performance by not needlessly spinning in spinlocks for unrelated resources. */
|
||||
PRIVILEGED_DATA static portMUX_TYPE xTaskQueueMutex = portMUX_INITIALIZER_UNLOCKED;
|
||||
PRIVILEGED_DATA static portMUX_TYPE xTickCountMutex = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
@ -611,15 +610,6 @@ static void prvInitialiseNewTask( TaskFunction_t pxTaskCode,
|
|||
static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB, TaskFunction_t pxTaskCode, const BaseType_t xCoreID ) PRIVILEGED_FUNCTION;
|
||||
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
static void vTaskInitializeLocalMuxes( void )
|
||||
{
|
||||
vPortCPUInitializeMutex(&xTaskQueueMutex);
|
||||
vPortCPUInitializeMutex(&xTickCountMutex);
|
||||
xMutexesInitialised = pdTRUE;
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
@ -1195,7 +1185,7 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB, TaskFunction_t pxTaskCode
|
|||
TickType_t xTimeToWake;
|
||||
BaseType_t xAlreadyYielded=pdFALSE, xShouldDelay = pdFALSE;
|
||||
|
||||
ets_printf("ToDo %s\n", __FUNCTION__);
|
||||
UNTESTED_FUNCTION();
|
||||
configASSERT( pxPreviousWakeTime );
|
||||
configASSERT( ( xTimeIncrement > 0U ) );
|
||||
configASSERT( uxSchedulerSuspended[ xPortGetCoreID() ] == 0 );
|
||||
|
@ -1365,7 +1355,7 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB, TaskFunction_t pxTaskCode
|
|||
List_t *pxStateList;
|
||||
const TCB_t * const pxTCB = ( TCB_t * ) xTask;
|
||||
|
||||
ets_printf("ToDo %s\n", __FUNCTION__);
|
||||
UNTESTED_FUNCTION();
|
||||
configASSERT( pxTCB );
|
||||
|
||||
if( pxTCB == pxCurrentTCB[ xPortGetCoreID() ] )
|
||||
|
@ -1435,7 +1425,7 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB, TaskFunction_t pxTaskCode
|
|||
TCB_t *pxTCB;
|
||||
UBaseType_t uxReturn;
|
||||
|
||||
ets_printf("ToDo %s\n", __FUNCTION__);
|
||||
UNTESTED_FUNCTION();
|
||||
taskENTER_CRITICAL(&xTaskQueueMutex);
|
||||
{
|
||||
/* If null is passed in here then we are changing the
|
||||
|
@ -1643,7 +1633,7 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB, TaskFunction_t pxTaskCode
|
|||
{
|
||||
TCB_t *pxTCB;
|
||||
|
||||
ets_printf("ToDo %s\n", __FUNCTION__);
|
||||
UNTESTED_FUNCTION();
|
||||
taskENTER_CRITICAL(&xTaskQueueMutex);
|
||||
{
|
||||
/* If null is passed in here then it is the running task that is
|
||||
|
@ -1784,7 +1774,7 @@ static void prvAddNewTaskToReadyList( TCB_t *pxNewTCB, TaskFunction_t pxTaskCode
|
|||
{
|
||||
TCB_t * const pxTCB = ( TCB_t * ) xTaskToResume;
|
||||
|
||||
ets_printf("ToDo %s\n", __FUNCTION__);
|
||||
UNTESTED_FUNCTION();
|
||||
/* It does not make sense to resume the calling task. */
|
||||
configASSERT( xTaskToResume );
|
||||
|
||||
|
@ -2047,10 +2037,6 @@ BaseType_t xAlreadyYielded = pdFALSE;
|
|||
scheduler has been resumed it is safe to move all the pending ready
|
||||
tasks from this list into their appropriate ready list. */
|
||||
|
||||
//This uses a mux, but can be called before tasks are scheduled. Make sure muxes are inited.
|
||||
/* Initialize mutexes, if they're not already initialized. */
|
||||
if (xMutexesInitialised == pdFALSE) vTaskInitializeLocalMuxes();
|
||||
|
||||
taskENTER_CRITICAL(&xTaskQueueMutex);
|
||||
{
|
||||
--uxSchedulerSuspended[ xPortGetCoreID() ];
|
||||
|
@ -2190,7 +2176,7 @@ UBaseType_t uxTaskGetNumberOfTasks( void )
|
|||
{
|
||||
UBaseType_t uxTask = 0, uxQueue = configMAX_PRIORITIES;
|
||||
|
||||
ets_printf("ToDo %s\n", __FUNCTION__);
|
||||
UNTESTED_FUNCTION();
|
||||
vTaskSuspendAll(); //WARNING: This only suspends one CPU. ToDo: suspend others as well. Mux using taskQueueMutex maybe?
|
||||
{
|
||||
/* Is there a space in the array for each task in the system? */
|
||||
|
@ -3362,7 +3348,7 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters )
|
|||
{
|
||||
TCB_t *pxTCB;
|
||||
|
||||
ets_printf("ToDo %s\n", __FUNCTION__);
|
||||
UNTESTED_FUNCTION();
|
||||
/* If null is passed in here then we are deleting ourselves. */
|
||||
pxTCB = prvGetTCBFromHandle( xTaskToModify );
|
||||
|
||||
|
@ -3488,6 +3474,18 @@ static void prvAddCurrentTaskToDelayedList( const BaseType_t xCoreID, const Tick
|
|||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
BaseType_t xTaskGetAffinity( TaskHandle_t xTask )
|
||||
{
|
||||
TCB_t *pxTCB;
|
||||
UBaseType_t uxReturn;
|
||||
|
||||
pxTCB = prvGetTCBFromHandle( xTask );
|
||||
|
||||
return pxTCB->xCoreID;
|
||||
}
|
||||
/*-----------------------------------------------------------*/
|
||||
|
||||
|
||||
#if ( configUSE_TRACE_FACILITY == 1 )
|
||||
|
||||
static UBaseType_t prvListTaskWithinSingleList( TaskStatus_t *pxTaskStatusArray, List_t *pxList, eTaskState eState )
|
||||
|
@ -3495,6 +3493,7 @@ static void prvAddCurrentTaskToDelayedList( const BaseType_t xCoreID, const Tick
|
|||
volatile TCB_t *pxNextTCB, *pxFirstTCB;
|
||||
UBaseType_t uxTask = 0;
|
||||
|
||||
UNTESTED_FUNCTION();
|
||||
if( listCURRENT_LIST_LENGTH( pxList ) > ( UBaseType_t ) 0 )
|
||||
{
|
||||
listGET_OWNER_OF_NEXT_ENTRY( pxFirstTCB, pxList );
|
||||
|
@ -3601,6 +3600,7 @@ static void prvAddCurrentTaskToDelayedList( const BaseType_t xCoreID, const Tick
|
|||
uint8_t *pucEndOfStack;
|
||||
UBaseType_t uxReturn;
|
||||
|
||||
UNTESTED_FUNCTION();
|
||||
pxTCB = prvGetTCBFromHandle( xTask );
|
||||
|
||||
#if portSTACK_GROWTH < 0
|
||||
|
@ -4050,6 +4050,7 @@ scheduler will re-enable the interrupts instead. */
|
|||
TaskStatus_t *pxTaskStatusArray;
|
||||
volatile UBaseType_t uxArraySize, x;
|
||||
char cStatus;
|
||||
UNTESTED_FUNCTION();
|
||||
|
||||
/*
|
||||
* PLEASE NOTE:
|
||||
|
@ -4146,6 +4147,7 @@ scheduler will re-enable the interrupts instead. */
|
|||
volatile UBaseType_t uxArraySize, x;
|
||||
uint32_t ulTotalTime, ulStatsAsPercentage;
|
||||
|
||||
UNTESTED_FUNCTION();
|
||||
#if( configUSE_TRACE_FACILITY != 1 )
|
||||
{
|
||||
#error configUSE_TRACE_FACILITY must also be set to 1 in FreeRTOSConfig.h to use vTaskGetRunTimeStats().
|
||||
|
@ -4306,6 +4308,7 @@ TickType_t uxReturn;
|
|||
TickType_t xTimeToWake;
|
||||
uint32_t ulReturn;
|
||||
|
||||
UNTESTED_FUNCTION();
|
||||
taskENTER_CRITICAL(&xTaskQueueMutex);
|
||||
{
|
||||
/* Only block if the notification count is not already non-zero. */
|
||||
|
@ -4416,6 +4419,7 @@ TickType_t uxReturn;
|
|||
TickType_t xTimeToWake;
|
||||
BaseType_t xReturn;
|
||||
|
||||
UNTESTED_FUNCTION();
|
||||
taskENTER_CRITICAL(&xTaskQueueMutex);
|
||||
{
|
||||
/* Only block if a notification is not already pending. */
|
||||
|
@ -4538,6 +4542,7 @@ TickType_t uxReturn;
|
|||
eNotifyValue eOriginalNotifyState;
|
||||
BaseType_t xReturn = pdPASS;
|
||||
|
||||
UNTESTED_FUNCTION();
|
||||
configASSERT( xTaskToNotify );
|
||||
pxTCB = ( TCB_t * ) xTaskToNotify;
|
||||
|
||||
|
@ -4622,6 +4627,7 @@ TickType_t uxReturn;
|
|||
eNotifyValue eOriginalNotifyState;
|
||||
BaseType_t xReturn = pdPASS;
|
||||
|
||||
UNTESTED_FUNCTION();
|
||||
configASSERT( xTaskToNotify );
|
||||
|
||||
pxTCB = ( TCB_t * ) xTaskToNotify;
|
||||
|
@ -4715,6 +4721,7 @@ TickType_t uxReturn;
|
|||
TCB_t * pxTCB;
|
||||
eNotifyValue eOriginalNotifyState;
|
||||
|
||||
UNTESTED_FUNCTION();
|
||||
configASSERT( xTaskToNotify );
|
||||
|
||||
|
||||
|
|
|
@ -92,6 +92,12 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|||
|
||||
#include "xtensa_rtos.h"
|
||||
|
||||
/*
|
||||
Define for workaround: pin no-cpu-affinity tasks to a cpu when fpu is used.
|
||||
Please change this when the tcb structure is changed
|
||||
*/
|
||||
#define TASKTCB_XCOREID_OFFSET (0x3C+configMAX_TASK_NAME_LEN+3)&~3
|
||||
.extern pxCurrentTCB
|
||||
|
||||
/* Enable stack backtrace across exception/interrupt - see below */
|
||||
#define XT_DEBUG_BACKTRACE 0
|
||||
|
@ -892,6 +898,20 @@ _xt_coproc_exc:
|
|||
addx4 a0, a5, a0 /* a0 = &_xt_coproc_mask[n] */
|
||||
l32i a0, a0, 0 /* a0 = (n << 16) | (1 << n) */
|
||||
|
||||
/* TODO: Remove this as soon as coprocessor state moving works across cores - JD */
|
||||
/* FPU operations are incompatible with non-pinned tasks. If we have a FPU operation
|
||||
here, to keep the entire thing from crashing, it's better to pin the task to whatever
|
||||
core we're running on now. */
|
||||
movi a2, pxCurrentTCB
|
||||
getcoreid a3
|
||||
slli a3, a3, 2
|
||||
add a2, a2, a3
|
||||
l32i a2, a2, 0 /* a2 = start of pxCurrentTCB[cpuid] */
|
||||
addi a2, a2, TASKTCB_XCOREID_OFFSET /* offset to xCoreID in tcb struct */
|
||||
getcoreid a3
|
||||
s32i a3, a2, 0 /* store current cpuid */
|
||||
|
||||
/* Grab correct xt_coproc_owner_sa for this core */
|
||||
getcoreid a2
|
||||
movi a3, XCHAL_CP_MAX << 2
|
||||
mull a2, a2, a3
|
||||
|
|
|
@ -1442,8 +1442,15 @@ lwip_sendto(int s, const void *data, size_t size, int flags,
|
|||
#ifdef LWIP_ESP8266
|
||||
/*fix the code for getting the UDP proto's remote information by liuh at 2014.8.27*/
|
||||
if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_UDP){
|
||||
if(NETCONNTYPE_ISIPV6(netconn_type(sock->conn))) {
|
||||
memcpy(&buf.addr.u_addr.ip6.addr, sock->conn->pcb.udp->remote_ip.u_addr.ip6.addr,16);
|
||||
remote_port = sock->conn->pcb.udp->remote_port;
|
||||
IP_SET_TYPE(&buf.addr, IPADDR_TYPE_V6);
|
||||
} else {
|
||||
buf.addr.u_addr.ip4.addr = sock->conn->pcb.udp->remote_ip.u_addr.ip4.addr;
|
||||
remote_port = sock->conn->pcb.udp->remote_port;
|
||||
IP_SET_TYPE(&buf.addr, IPADDR_TYPE_V4);
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
remote_port = 0;
|
||||
|
|
|
@ -6,6 +6,6 @@ COMPONENT_ADD_INCLUDEDIRS := include/lwip include/lwip/port include/lwip/posix
|
|||
|
||||
COMPONENT_SRCDIRS := api apps/sntp apps core/ipv4 core/ipv6 core netif port/freertos port/netif port
|
||||
|
||||
CFLAGS += -Wno-error=address -Waddress
|
||||
CFLAGS += -Wno-address -Wno-unused-variable -Wno-unused-but-set-variable
|
||||
|
||||
include $(IDF_PATH)/make/component_common.mk
|
||||
|
|
|
@ -38,6 +38,11 @@
|
|||
#include "freertos/queue.h"
|
||||
#include "freertos/semphr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
typedef xSemaphoreHandle sys_sem_t;
|
||||
typedef xSemaphoreHandle sys_mutex_t;
|
||||
typedef xTaskHandle sys_thread_t;
|
||||
|
@ -68,5 +73,10 @@ 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);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __SYS_ARCH_H__ */
|
||||
|
||||
|
|
|
@ -10,6 +10,10 @@
|
|||
|
||||
#include "lwip/err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
err_t wlanif_init(struct netif *netif);
|
||||
|
||||
void wlanif_input(struct netif *netif, void *buffer, u16_t len, void* eb);
|
||||
|
@ -20,4 +24,8 @@ wifi_interface_t wifi_get_interface(void *dev);
|
|||
|
||||
void netif_reg_addr_change_cb(void* cb);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _WLAN_LWIP_IF_H_ */
|
||||
|
|
37
components/mbedtls/Kconfig
Normal file
37
components/mbedtls/Kconfig
Normal file
|
@ -0,0 +1,37 @@
|
|||
menu "mbedTLS"
|
||||
|
||||
config MBEDTLS_SSL_MAX_CONTENT_LEN
|
||||
int "TLS maximum message content length"
|
||||
default 16384
|
||||
range 512 16384
|
||||
help
|
||||
Maximum TLS message length (in bytes) supported by mbedTLS.
|
||||
|
||||
16384 is the default and this value is required to comply
|
||||
fully with TLS standards.
|
||||
|
||||
However you can set a lower value in order to save RAM. This
|
||||
is safe if the other end of the connection supports Maximum
|
||||
Fragment Length Negotiation Extension (max_fragment_length,
|
||||
see RFC6066) or you know for certain that it will never send a
|
||||
message longer than a certain number of bytes.
|
||||
|
||||
If the value is set too low, symptoms are a failed TLS
|
||||
handshake or a return value of MBEDTLS_ERR_SSL_INVALID_RECORD
|
||||
(-0x7200).
|
||||
|
||||
config MBEDTLS_DEBUG
|
||||
bool "Enable mbedTLS debugging"
|
||||
default "no"
|
||||
help
|
||||
Enable mbedTLS debugging functions.
|
||||
|
||||
If this option is enabled, use the mbedtls_debug_set_threshold()
|
||||
and mbedtls_ssl_conf_dbg() functions to obtain debugging output
|
||||
from mbedTLS.
|
||||
|
||||
Note thatm mbedTLS debugging is not related to the ESP logging
|
||||
functionality. See the "https_request_main" example for a
|
||||
sample function which connects the two together.
|
||||
|
||||
endmenu
|
|
@ -27,6 +27,8 @@
|
|||
#ifndef MBEDTLS_CONFIG_H
|
||||
#define MBEDTLS_CONFIG_H
|
||||
|
||||
#include "sdkconfig.h"
|
||||
|
||||
#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
|
||||
#define _CRT_SECURE_NO_DEPRECATE 1
|
||||
#endif
|
||||
|
@ -1659,7 +1661,9 @@
|
|||
*
|
||||
* This module provides debugging functions.
|
||||
*/
|
||||
#if CONFIG_MBEDTLS_DEBUG
|
||||
#define MBEDTLS_DEBUG_C
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \def MBEDTLS_DES_C
|
||||
|
@ -2481,7 +2485,7 @@
|
|||
|
||||
/* SSL options */
|
||||
|
||||
#define MBEDTLS_SSL_MAX_CONTENT_LEN 5120 /**< Maxium fragment length in bytes, determines the size of each of the two internal I/O buffers */
|
||||
#define MBEDTLS_SSL_MAX_CONTENT_LEN CONFIG_MBEDTLS_SSL_MAX_CONTENT_LEN /**< Maxium fragment length in bytes, determines the size of each of the two internal I/O buffers */
|
||||
//#define MBEDTLS_SSL_DEFAULT_TICKET_LIFETIME 86400 /**< Lifetime of session tickets (if enabled) */
|
||||
//#define MBEDTLS_PSK_MAX_LEN 32 /**< Max size of TLS pre-shared keys, in bytes (default 256 bits) */
|
||||
//#define MBEDTLS_SSL_COOKIE_TIMEOUT 60 /**< Default expiration delay of DTLS cookies, in seconds if HAVE_TIME, or in number of cookies issued */
|
||||
|
|
23
components/nghttp/COPYING
Normal file
23
components/nghttp/COPYING
Normal file
|
@ -0,0 +1,23 @@
|
|||
The MIT License
|
||||
|
||||
Copyright (c) 2012, 2014, 2015, 2016 Tatsuhiro Tsujikawa
|
||||
Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
1
components/nghttp/LICENSE
Normal file
1
components/nghttp/LICENSE
Normal file
|
@ -0,0 +1 @@
|
|||
See COPYING
|
17
components/nghttp/Makefile
Normal file
17
components/nghttp/Makefile
Normal file
|
@ -0,0 +1,17 @@
|
|||
#
|
||||
# Component Makefile
|
||||
#
|
||||
# This Makefile should, at the very least, just include $(SDK_PATH)/Makefile. 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 SDK documents if you need to do this.
|
||||
#
|
||||
COMPONENT_ADD_INCLUDEDIRS := port/include include
|
||||
|
||||
COMPONENT_SRCDIRS := library port
|
||||
|
||||
#EXTRA_CFLAGS += -DMBEDTLS_CONFIG_FILE='"mbedtls/esp_config.h"'
|
||||
|
||||
EXTRA_CFLAGS := -Wno-error=address -Waddress -DHAVE_CONFIG_H
|
||||
|
||||
include $(IDF_PATH)/make/component.mk
|
4
components/nghttp/Makefile.projbuild
Normal file
4
components/nghttp/Makefile.projbuild
Normal file
|
@ -0,0 +1,4 @@
|
|||
# Anyone compiling mbedTLS code needs the name of the
|
||||
# alternative config file
|
||||
|
||||
CFLAGS += -DHAVE_CONFIG_H
|
1
components/nghttp/README
Normal file
1
components/nghttp/README
Normal file
|
@ -0,0 +1 @@
|
|||
See README.rst
|
9
components/nghttp/component.mk
Normal file
9
components/nghttp/component.mk
Normal file
|
@ -0,0 +1,9 @@
|
|||
#
|
||||
# Component Makefile
|
||||
#
|
||||
|
||||
COMPONENT_ADD_INCLUDEDIRS := port/include include
|
||||
|
||||
COMPONENT_SRCDIRS := library port
|
||||
|
||||
include $(IDF_PATH)/make/component_common.mk
|
5030
components/nghttp/include/nghttp2/nghttp2.h
Normal file
5030
components/nghttp/include/nghttp2/nghttp2.h
Normal file
File diff suppressed because it is too large
Load diff
42
components/nghttp/include/nghttp2/nghttp2ver.h
Normal file
42
components/nghttp/include/nghttp2/nghttp2ver.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2012, 2013 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2VER_H
|
||||
#define NGHTTP2VER_H
|
||||
|
||||
/**
|
||||
* @macro
|
||||
* Version number of the nghttp2 library release
|
||||
*/
|
||||
#define NGHTTP2_VERSION "@PACKAGE_VERSION@"
|
||||
|
||||
/**
|
||||
* @macro
|
||||
* Numerical representation of the version number of the nghttp2 library
|
||||
* release. This is a 24 bit number with 8 bits for major number, 8 bits
|
||||
* for minor and 8 bits for patch. Version 1.2.3 becomes 0x010203.
|
||||
*/
|
||||
#define NGHTTP2_VERSION_NUM 0x010203
|
||||
|
||||
#endif /* NGHTTP2VER_H */
|
388
components/nghttp/include/nghttp2_buf.h
Normal file
388
components/nghttp/include/nghttp2_buf.h
Normal file
|
@ -0,0 +1,388 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2014 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2_BUF_H
|
||||
#define NGHTTP2_BUF_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
|
||||
#include "nghttp2_int.h"
|
||||
#include "nghttp2_mem.h"
|
||||
|
||||
typedef struct {
|
||||
/* This points to the beginning of the buffer. The effective range
|
||||
of buffer is [begin, end). */
|
||||
uint8_t *begin;
|
||||
/* This points to the memory one byte beyond the end of the
|
||||
buffer. */
|
||||
uint8_t *end;
|
||||
/* The position indicator for effective start of the buffer. pos <=
|
||||
last must be hold. */
|
||||
uint8_t *pos;
|
||||
/* The position indicator for effective one beyond of the end of the
|
||||
buffer. last <= end must be hold. */
|
||||
uint8_t *last;
|
||||
/* Mark arbitrary position in buffer [begin, end) */
|
||||
uint8_t *mark;
|
||||
} nghttp2_buf;
|
||||
|
||||
#define nghttp2_buf_len(BUF) ((size_t)((BUF)->last - (BUF)->pos))
|
||||
#define nghttp2_buf_avail(BUF) ((size_t)((BUF)->end - (BUF)->last))
|
||||
#define nghttp2_buf_mark_avail(BUF) ((size_t)((BUF)->mark - (BUF)->last))
|
||||
#define nghttp2_buf_cap(BUF) ((size_t)((BUF)->end - (BUF)->begin))
|
||||
|
||||
#define nghttp2_buf_pos_offset(BUF) ((size_t)((BUF)->pos - (BUF)->begin))
|
||||
#define nghttp2_buf_last_offset(BUF) ((size_t)((BUF)->last - (BUF)->begin))
|
||||
|
||||
#define nghttp2_buf_shift_right(BUF, AMT) \
|
||||
do { \
|
||||
(BUF)->pos += AMT; \
|
||||
(BUF)->last += AMT; \
|
||||
} while (0)
|
||||
|
||||
#define nghttp2_buf_shift_left(BUF, AMT) \
|
||||
do { \
|
||||
(BUF)->pos -= AMT; \
|
||||
(BUF)->last -= AMT; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Initializes the |buf|. No memory is allocated in this function. Use
|
||||
* nghttp2_buf_reserve() to allocate memory.
|
||||
*/
|
||||
void nghttp2_buf_init(nghttp2_buf *buf);
|
||||
|
||||
/*
|
||||
* Initializes the |buf| and allocates at least |initial| bytes of
|
||||
* memory.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory
|
||||
*/
|
||||
int nghttp2_buf_init2(nghttp2_buf *buf, size_t initial, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Frees buffer in |buf|.
|
||||
*/
|
||||
void nghttp2_buf_free(nghttp2_buf *buf, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Extends buffer so that nghttp2_buf_cap() returns at least
|
||||
* |new_cap|. If extensions took place, buffer pointers in |buf| will
|
||||
* change.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the followings
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory
|
||||
*/
|
||||
int nghttp2_buf_reserve(nghttp2_buf *buf, size_t new_cap, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Resets pos, last, mark member of |buf| to buf->begin.
|
||||
*/
|
||||
void nghttp2_buf_reset(nghttp2_buf *buf);
|
||||
|
||||
/*
|
||||
* Initializes |buf| using supplied buffer |begin| of length
|
||||
* |len|. Semantically, the application should not call *_reserve() or
|
||||
* nghttp2_free() functions for |buf|.
|
||||
*/
|
||||
void nghttp2_buf_wrap_init(nghttp2_buf *buf, uint8_t *begin, size_t len);
|
||||
|
||||
struct nghttp2_buf_chain;
|
||||
|
||||
typedef struct nghttp2_buf_chain nghttp2_buf_chain;
|
||||
|
||||
/* Chains 2 buffers */
|
||||
struct nghttp2_buf_chain {
|
||||
/* Points to the subsequent buffer. NULL if there is no such
|
||||
buffer. */
|
||||
nghttp2_buf_chain *next;
|
||||
nghttp2_buf buf;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
/* Points to the first buffer */
|
||||
nghttp2_buf_chain *head;
|
||||
/* Buffer pointer where write occurs. */
|
||||
nghttp2_buf_chain *cur;
|
||||
/* Memory allocator */
|
||||
nghttp2_mem *mem;
|
||||
/* The buffer capacity of each buf */
|
||||
size_t chunk_length;
|
||||
/* The maximum number of nghttp2_buf_chain */
|
||||
size_t max_chunk;
|
||||
/* The number of nghttp2_buf_chain allocated */
|
||||
size_t chunk_used;
|
||||
/* The number of nghttp2_buf_chain to keep on reset */
|
||||
size_t chunk_keep;
|
||||
/* pos offset from begin in each buffers. On initialization and
|
||||
reset, buf->pos and buf->last are positioned at buf->begin +
|
||||
offset. */
|
||||
size_t offset;
|
||||
} nghttp2_bufs;
|
||||
|
||||
/*
|
||||
* This is the same as calling nghttp2_bufs_init2 with the given
|
||||
* arguments and offset = 0.
|
||||
*/
|
||||
int nghttp2_bufs_init(nghttp2_bufs *bufs, size_t chunk_length, size_t max_chunk,
|
||||
nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* This is the same as calling nghttp2_bufs_init3 with the given
|
||||
* arguments and chunk_keep = max_chunk.
|
||||
*/
|
||||
int nghttp2_bufs_init2(nghttp2_bufs *bufs, size_t chunk_length,
|
||||
size_t max_chunk, size_t offset, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Initializes |bufs|. Each buffer size is given in the
|
||||
* |chunk_length|. The maximum number of buffers is given in the
|
||||
* |max_chunk|. On reset, first |chunk_keep| buffers are kept and
|
||||
* remaining buffers are deleted. Each buffer will have bufs->pos and
|
||||
* bufs->last shifted to left by |offset| bytes on creation and reset.
|
||||
*
|
||||
* This function allocates first buffer. bufs->head and bufs->cur
|
||||
* will point to the first buffer after this call.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* NGHTTP2_ERR_INVALID_ARGUMENT
|
||||
* chunk_keep is 0; or max_chunk < chunk_keep; or offset is too
|
||||
* long.
|
||||
*/
|
||||
int nghttp2_bufs_init3(nghttp2_bufs *bufs, size_t chunk_length,
|
||||
size_t max_chunk, size_t chunk_keep, size_t offset,
|
||||
nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Frees any related resources to the |bufs|.
|
||||
*/
|
||||
void nghttp2_bufs_free(nghttp2_bufs *bufs);
|
||||
|
||||
/*
|
||||
* Initializes |bufs| using supplied buffer |begin| of length |len|.
|
||||
* The first buffer bufs->head uses buffer |begin|. The buffer size
|
||||
* is fixed and no allocate extra chunk buffer is allocated. In other
|
||||
* words, max_chunk = chunk_keep = 1. To free the resource allocated
|
||||
* for |bufs|, use nghttp2_bufs_wrap_free().
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
*/
|
||||
int nghttp2_bufs_wrap_init(nghttp2_bufs *bufs, uint8_t *begin, size_t len,
|
||||
nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Frees any related resource to the |bufs|. This function does not
|
||||
* free supplied buffer provided in nghttp2_bufs_wrap_init().
|
||||
*/
|
||||
void nghttp2_bufs_wrap_free(nghttp2_bufs *bufs);
|
||||
|
||||
/*
|
||||
* Reallocates internal buffer using |chunk_length|. The max_chunk,
|
||||
* chunk_keep and offset do not change. After successful allocation
|
||||
* of new buffer, previous buffers are deallocated without copying
|
||||
* anything into new buffers. chunk_used is reset to 1.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* NGHTTP2_ERR_INVALID_ARGUMENT
|
||||
* chunk_length < offset
|
||||
*/
|
||||
int nghttp2_bufs_realloc(nghttp2_bufs *bufs, size_t chunk_length);
|
||||
|
||||
/*
|
||||
* Appends the |data| of length |len| to the |bufs|. The write starts
|
||||
* at bufs->cur->buf.last. A new buffers will be allocated to store
|
||||
* all data.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* NGHTTP2_ERR_BUFFER_ERROR
|
||||
* Out of buffer space.
|
||||
*/
|
||||
int nghttp2_bufs_add(nghttp2_bufs *bufs, const void *data, size_t len);
|
||||
|
||||
/*
|
||||
* Appends a single byte |b| to the |bufs|. The write starts at
|
||||
* bufs->cur->buf.last. A new buffers will be allocated to store all
|
||||
* data.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* NGHTTP2_ERR_BUFFER_ERROR
|
||||
* Out of buffer space.
|
||||
*/
|
||||
int nghttp2_bufs_addb(nghttp2_bufs *bufs, uint8_t b);
|
||||
|
||||
/*
|
||||
* Behaves like nghttp2_bufs_addb(), but this does not update
|
||||
* buf->last pointer.
|
||||
*/
|
||||
int nghttp2_bufs_addb_hold(nghttp2_bufs *bufs, uint8_t b);
|
||||
|
||||
#define nghttp2_bufs_fast_addb(BUFS, B) \
|
||||
do { \
|
||||
*(BUFS)->cur->buf.last++ = B; \
|
||||
} while (0)
|
||||
|
||||
#define nghttp2_bufs_fast_addb_hold(BUFS, B) \
|
||||
do { \
|
||||
*(BUFS)->cur->buf.last = B; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Performs bitwise-OR of |b| at bufs->cur->buf.last. A new buffers
|
||||
* will be allocated if necessary.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* NGHTTP2_ERR_BUFFER_ERROR
|
||||
* Out of buffer space.
|
||||
*/
|
||||
int nghttp2_bufs_orb(nghttp2_bufs *bufs, uint8_t b);
|
||||
|
||||
/*
|
||||
* Behaves like nghttp2_bufs_orb(), but does not update buf->last
|
||||
* pointer.
|
||||
*/
|
||||
int nghttp2_bufs_orb_hold(nghttp2_bufs *bufs, uint8_t b);
|
||||
|
||||
#define nghttp2_bufs_fast_orb(BUFS, B) \
|
||||
do { \
|
||||
uint8_t **p = &(BUFS)->cur->buf.last; \
|
||||
**p = (uint8_t)(**p | (B)); \
|
||||
++(*p); \
|
||||
} while (0)
|
||||
|
||||
#define nghttp2_bufs_fast_orb_hold(BUFS, B) \
|
||||
do { \
|
||||
uint8_t *p = (BUFS)->cur->buf.last; \
|
||||
*p = (uint8_t)(*p | (B)); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Copies all data stored in |bufs| to the contiguous buffer. This
|
||||
* function allocates the contiguous memory to store all data in
|
||||
* |bufs| and assigns it to |*out|.
|
||||
*
|
||||
* The contents of |bufs| is left unchanged.
|
||||
*
|
||||
* This function returns the length of copied data and assigns the
|
||||
* pointer to copied data to |*out| if it succeeds, or one of the
|
||||
* following negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory
|
||||
*/
|
||||
ssize_t nghttp2_bufs_remove(nghttp2_bufs *bufs, uint8_t **out);
|
||||
|
||||
/*
|
||||
* Copies all data stored in |bufs| to |out|. This function assumes
|
||||
* that the buffer space pointed by |out| has at least
|
||||
* nghttp2_bufs(bufs) bytes.
|
||||
*
|
||||
* The contents of |bufs| is left unchanged.
|
||||
*
|
||||
* This function returns the length of copied data.
|
||||
*/
|
||||
size_t nghttp2_bufs_remove_copy(nghttp2_bufs *bufs, uint8_t *out);
|
||||
|
||||
/*
|
||||
* Resets |bufs| and makes the buffers empty.
|
||||
*/
|
||||
void nghttp2_bufs_reset(nghttp2_bufs *bufs);
|
||||
|
||||
/*
|
||||
* Moves bufs->cur to bufs->cur->next. If resulting bufs->cur is
|
||||
* NULL, this function allocates new buffers and bufs->cur points to
|
||||
* it.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory
|
||||
* NGHTTP2_ERR_BUFFER_ERROR
|
||||
* Out of buffer space.
|
||||
*/
|
||||
int nghttp2_bufs_advance(nghttp2_bufs *bufs);
|
||||
|
||||
/* Sets bufs->cur to bufs->head */
|
||||
#define nghttp2_bufs_rewind(BUFS) \
|
||||
do { \
|
||||
(BUFS)->cur = (BUFS)->head; \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Move bufs->cur, from the current position, using next member, to
|
||||
* the last buf which has nghttp2_buf_len(buf) > 0 without seeing buf
|
||||
* which satisfies nghttp2_buf_len(buf) == 0. If
|
||||
* nghttp2_buf_len(&bufs->cur->buf) == 0 or bufs->cur->next is NULL,
|
||||
* bufs->cur is unchanged.
|
||||
*/
|
||||
void nghttp2_bufs_seek_last_present(nghttp2_bufs *bufs);
|
||||
|
||||
/*
|
||||
* Returns nonzero if bufs->cur->next is not emtpy.
|
||||
*/
|
||||
int nghttp2_bufs_next_present(nghttp2_bufs *bufs);
|
||||
|
||||
#define nghttp2_bufs_cur_avail(BUFS) nghttp2_buf_avail(&(BUFS)->cur->buf)
|
||||
|
||||
/*
|
||||
* Returns the buffer length of |bufs|.
|
||||
*/
|
||||
size_t nghttp2_bufs_len(nghttp2_bufs *bufs);
|
||||
|
||||
#endif /* NGHTTP2_BUF_H */
|
117
components/nghttp/include/nghttp2_callbacks.h
Normal file
117
components/nghttp/include/nghttp2_callbacks.h
Normal file
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2014 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2_CALLBACKS_H
|
||||
#define NGHTTP2_CALLBACKS_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
|
||||
/*
|
||||
* Callback functions.
|
||||
*/
|
||||
struct nghttp2_session_callbacks {
|
||||
/**
|
||||
* Callback function invoked when the session wants to send data to
|
||||
* the remote peer. This callback is not necessary if the
|
||||
* application uses solely `nghttp2_session_mem_send()` to serialize
|
||||
* data to transmit.
|
||||
*/
|
||||
nghttp2_send_callback send_callback;
|
||||
/**
|
||||
* Callback function invoked when the session wants to receive data
|
||||
* from the remote peer. This callback is not necessary if the
|
||||
* application uses solely `nghttp2_session_mem_recv()` to process
|
||||
* received data.
|
||||
*/
|
||||
nghttp2_recv_callback recv_callback;
|
||||
/**
|
||||
* Callback function invoked by `nghttp2_session_recv()` when a
|
||||
* frame is received.
|
||||
*/
|
||||
nghttp2_on_frame_recv_callback on_frame_recv_callback;
|
||||
/**
|
||||
* Callback function invoked by `nghttp2_session_recv()` when an
|
||||
* invalid non-DATA frame is received.
|
||||
*/
|
||||
nghttp2_on_invalid_frame_recv_callback on_invalid_frame_recv_callback;
|
||||
/**
|
||||
* Callback function invoked when a chunk of data in DATA frame is
|
||||
* received.
|
||||
*/
|
||||
nghttp2_on_data_chunk_recv_callback on_data_chunk_recv_callback;
|
||||
/**
|
||||
* Callback function invoked before a non-DATA frame is sent.
|
||||
*/
|
||||
nghttp2_before_frame_send_callback before_frame_send_callback;
|
||||
/**
|
||||
* Callback function invoked after a frame is sent.
|
||||
*/
|
||||
nghttp2_on_frame_send_callback on_frame_send_callback;
|
||||
/**
|
||||
* The callback function invoked when a non-DATA frame is not sent
|
||||
* because of an error.
|
||||
*/
|
||||
nghttp2_on_frame_not_send_callback on_frame_not_send_callback;
|
||||
/**
|
||||
* Callback function invoked when the stream is closed.
|
||||
*/
|
||||
nghttp2_on_stream_close_callback on_stream_close_callback;
|
||||
/**
|
||||
* Callback function invoked when the reception of header block in
|
||||
* HEADERS or PUSH_PROMISE is started.
|
||||
*/
|
||||
nghttp2_on_begin_headers_callback on_begin_headers_callback;
|
||||
/**
|
||||
* Callback function invoked when a header name/value pair is
|
||||
* received.
|
||||
*/
|
||||
nghttp2_on_header_callback on_header_callback;
|
||||
nghttp2_on_header_callback2 on_header_callback2;
|
||||
/**
|
||||
* Callback function invoked when the library asks application how
|
||||
* many padding bytes are required for the transmission of the given
|
||||
* frame.
|
||||
*/
|
||||
nghttp2_select_padding_callback select_padding_callback;
|
||||
/**
|
||||
* The callback function used to determine the length allowed in
|
||||
* `nghttp2_data_source_read_callback()`
|
||||
*/
|
||||
nghttp2_data_source_read_length_callback read_length_callback;
|
||||
/**
|
||||
* Sets callback function invoked when a frame header is received.
|
||||
*/
|
||||
nghttp2_on_begin_frame_callback on_begin_frame_callback;
|
||||
nghttp2_send_data_callback send_data_callback;
|
||||
nghttp2_pack_extension_callback pack_extension_callback;
|
||||
nghttp2_unpack_extension_callback unpack_extension_callback;
|
||||
nghttp2_on_extension_chunk_recv_callback on_extension_chunk_recv_callback;
|
||||
nghttp2_error_callback error_callback;
|
||||
};
|
||||
|
||||
#endif /* NGHTTP2_CALLBACKS_H */
|
581
components/nghttp/include/nghttp2_frame.h
Normal file
581
components/nghttp/include/nghttp2_frame.h
Normal file
|
@ -0,0 +1,581 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2012 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2_FRAME_H
|
||||
#define NGHTTP2_FRAME_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
#include "nghttp2_hd.h"
|
||||
#include "nghttp2_buf.h"
|
||||
|
||||
#define NGHTTP2_STREAM_ID_MASK ((1u << 31) - 1)
|
||||
#define NGHTTP2_PRI_GROUP_ID_MASK ((1u << 31) - 1)
|
||||
#define NGHTTP2_PRIORITY_MASK ((1u << 31) - 1)
|
||||
#define NGHTTP2_WINDOW_SIZE_INCREMENT_MASK ((1u << 31) - 1)
|
||||
#define NGHTTP2_SETTINGS_ID_MASK ((1 << 24) - 1)
|
||||
|
||||
/* The number of bytes of frame header. */
|
||||
#define NGHTTP2_FRAME_HDLEN 9
|
||||
|
||||
#define NGHTTP2_MAX_FRAME_SIZE_MAX ((1 << 24) - 1)
|
||||
#define NGHTTP2_MAX_FRAME_SIZE_MIN (1 << 14)
|
||||
|
||||
#define NGHTTP2_MAX_PAYLOADLEN 8192//16384--LiuHan/0812
|
||||
/* The one frame buffer length for tranmission. We may use several of
|
||||
them to support CONTINUATION. To account for Pad Length field, we
|
||||
allocate extra 1 byte, which saves extra large memcopying. */
|
||||
#define NGHTTP2_FRAMEBUF_CHUNKLEN \
|
||||
(NGHTTP2_FRAME_HDLEN + 1 + NGHTTP2_MAX_PAYLOADLEN)
|
||||
|
||||
/* The default length of DATA frame payload. */
|
||||
#define NGHTTP2_DATA_PAYLOADLEN NGHTTP2_MAX_FRAME_SIZE_MIN
|
||||
|
||||
/* Maximum headers block size to send, calculated using
|
||||
nghttp2_hd_deflate_bound(). This is the default value, and can be
|
||||
overridden by nghttp2_option_set_max_send_header_block_size(). */
|
||||
#define NGHTTP2_MAX_HEADERSLEN 65536
|
||||
|
||||
/* The number of bytes for each SETTINGS entry */
|
||||
#define NGHTTP2_FRAME_SETTINGS_ENTRY_LENGTH 6
|
||||
|
||||
/* Length of priority related fields in HEADERS/PRIORITY frames */
|
||||
#define NGHTTP2_PRIORITY_SPECLEN 5
|
||||
|
||||
/* Maximum length of padding in bytes. */
|
||||
#define NGHTTP2_MAX_PADLEN 256
|
||||
|
||||
/* Union of extension frame payload */
|
||||
typedef union { nghttp2_ext_altsvc altsvc; } nghttp2_ext_frame_payload;
|
||||
|
||||
void nghttp2_frame_pack_frame_hd(uint8_t *buf, const nghttp2_frame_hd *hd);
|
||||
|
||||
void nghttp2_frame_unpack_frame_hd(nghttp2_frame_hd *hd, const uint8_t *buf);
|
||||
|
||||
/**
|
||||
* Initializes frame header |hd| with given parameters. Reserved bit
|
||||
* is set to 0.
|
||||
*/
|
||||
void nghttp2_frame_hd_init(nghttp2_frame_hd *hd, size_t length, uint8_t type,
|
||||
uint8_t flags, int32_t stream_id);
|
||||
|
||||
/**
|
||||
* Returns the number of priority field depending on the |flags|. If
|
||||
* |flags| has neither NGHTTP2_FLAG_PRIORITY_GROUP nor
|
||||
* NGHTTP2_FLAG_PRIORITY_DEPENDENCY set, return 0.
|
||||
*/
|
||||
size_t nghttp2_frame_priority_len(uint8_t flags);
|
||||
|
||||
/**
|
||||
* Packs the |pri_spec| in |buf|. This function assumes |buf| has
|
||||
* enough space for serialization.
|
||||
*/
|
||||
void nghttp2_frame_pack_priority_spec(uint8_t *buf,
|
||||
const nghttp2_priority_spec *pri_spec);
|
||||
|
||||
/**
|
||||
* Unpacks the priority specification from payload |payload| of length
|
||||
* |payloadlen| to |pri_spec|. The |flags| is used to determine what
|
||||
* kind of priority specification is in |payload|. This function
|
||||
* assumes the |payload| contains whole priority specification.
|
||||
*/
|
||||
void nghttp2_frame_unpack_priority_spec(nghttp2_priority_spec *pri_spec,
|
||||
uint8_t flags, const uint8_t *payload,
|
||||
size_t payloadlen);
|
||||
|
||||
/*
|
||||
* Returns the offset from the HEADERS frame payload where the
|
||||
* compressed header block starts. The frame payload does not include
|
||||
* frame header.
|
||||
*/
|
||||
size_t nghttp2_frame_headers_payload_nv_offset(nghttp2_headers *frame);
|
||||
|
||||
/*
|
||||
* Packs HEADERS frame |frame| in wire format and store it in |bufs|.
|
||||
* This function expands |bufs| as necessary to store frame.
|
||||
*
|
||||
* The caller must make sure that nghttp2_bufs_reset(bufs) is called
|
||||
* before calling this function.
|
||||
*
|
||||
* frame->hd.length is assigned after length is determined during
|
||||
* packing process. CONTINUATION frames are also serialized in this
|
||||
* function. This function does not handle padding.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or returns one of the
|
||||
* following negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_HEADER_COMP
|
||||
* The deflate operation failed.
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
*/
|
||||
int nghttp2_frame_pack_headers(nghttp2_bufs *bufs, nghttp2_headers *frame,
|
||||
nghttp2_hd_deflater *deflater);
|
||||
|
||||
/*
|
||||
* Unpacks HEADERS frame byte sequence into |frame|. This function
|
||||
* only unapcks bytes that come before name/value header block and
|
||||
* after possible Pad Length field.
|
||||
*
|
||||
* This function always succeeds and returns 0.
|
||||
*/
|
||||
int nghttp2_frame_unpack_headers_payload(nghttp2_headers *frame,
|
||||
const uint8_t *payload,
|
||||
size_t payloadlen);
|
||||
|
||||
/*
|
||||
* Packs PRIORITY frame |frame| in wire format and store it in
|
||||
* |bufs|.
|
||||
*
|
||||
* The caller must make sure that nghttp2_bufs_reset(bufs) is called
|
||||
* before calling this function.
|
||||
*
|
||||
* This function always succeeds and returns 0.
|
||||
*/
|
||||
int nghttp2_frame_pack_priority(nghttp2_bufs *bufs, nghttp2_priority *frame);
|
||||
|
||||
/*
|
||||
* Unpacks PRIORITY wire format into |frame|.
|
||||
*/
|
||||
void nghttp2_frame_unpack_priority_payload(nghttp2_priority *frame,
|
||||
const uint8_t *payload,
|
||||
size_t payloadlen);
|
||||
|
||||
/*
|
||||
* Packs RST_STREAM frame |frame| in wire frame format and store it in
|
||||
* |bufs|.
|
||||
*
|
||||
* The caller must make sure that nghttp2_bufs_reset(bufs) is called
|
||||
* before calling this function.
|
||||
*
|
||||
* This function always succeeds and returns 0.
|
||||
*/
|
||||
int nghttp2_frame_pack_rst_stream(nghttp2_bufs *bufs,
|
||||
nghttp2_rst_stream *frame);
|
||||
|
||||
/*
|
||||
* Unpacks RST_STREAM frame byte sequence into |frame|.
|
||||
*/
|
||||
void nghttp2_frame_unpack_rst_stream_payload(nghttp2_rst_stream *frame,
|
||||
const uint8_t *payload,
|
||||
size_t payloadlen);
|
||||
|
||||
/*
|
||||
* Packs SETTINGS frame |frame| in wire format and store it in
|
||||
* |bufs|.
|
||||
*
|
||||
* The caller must make sure that nghttp2_bufs_reset(bufs) is called
|
||||
* before calling this function.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or returns one of the
|
||||
* following negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_FRAME_SIZE_ERROR
|
||||
* The length of the frame is too large.
|
||||
*/
|
||||
int nghttp2_frame_pack_settings(nghttp2_bufs *bufs, nghttp2_settings *frame);
|
||||
|
||||
/*
|
||||
* Packs the |iv|, which includes |niv| entries, in the |buf|,
|
||||
* assuming the |buf| has at least 8 * |niv| bytes.
|
||||
*
|
||||
* Returns the number of bytes written into the |buf|.
|
||||
*/
|
||||
size_t nghttp2_frame_pack_settings_payload(uint8_t *buf,
|
||||
const nghttp2_settings_entry *iv,
|
||||
size_t niv);
|
||||
|
||||
void nghttp2_frame_unpack_settings_entry(nghttp2_settings_entry *iv,
|
||||
const uint8_t *payload);
|
||||
|
||||
/*
|
||||
* Initializes payload of frame->settings. The |frame| takes
|
||||
* ownership of |iv|.
|
||||
*/
|
||||
void nghttp2_frame_unpack_settings_payload(nghttp2_settings *frame,
|
||||
nghttp2_settings_entry *iv,
|
||||
size_t niv);
|
||||
|
||||
/*
|
||||
* Unpacks SETTINGS payload into |*iv_ptr|. The number of entries are
|
||||
* assigned to the |*niv_ptr|. This function allocates enough memory
|
||||
* to store the result in |*iv_ptr|. The caller is responsible to free
|
||||
* |*iv_ptr| after its use.
|
||||
*
|
||||
* This function returns 0 if it succeeds or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
*/
|
||||
int nghttp2_frame_unpack_settings_payload2(nghttp2_settings_entry **iv_ptr,
|
||||
size_t *niv_ptr,
|
||||
const uint8_t *payload,
|
||||
size_t payloadlen, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Packs PUSH_PROMISE frame |frame| in wire format and store it in
|
||||
* |bufs|. This function expands |bufs| as necessary to store
|
||||
* frame.
|
||||
*
|
||||
* The caller must make sure that nghttp2_bufs_reset(bufs) is called
|
||||
* before calling this function.
|
||||
*
|
||||
* frame->hd.length is assigned after length is determined during
|
||||
* packing process. CONTINUATION frames are also serialized in this
|
||||
* function. This function does not handle padding.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or returns one of the
|
||||
* following negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_HEADER_COMP
|
||||
* The deflate operation failed.
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
*/
|
||||
int nghttp2_frame_pack_push_promise(nghttp2_bufs *bufs,
|
||||
nghttp2_push_promise *frame,
|
||||
nghttp2_hd_deflater *deflater);
|
||||
|
||||
/*
|
||||
* Unpacks PUSH_PROMISE frame byte sequence into |frame|. This
|
||||
* function only unapcks bytes that come before name/value header
|
||||
* block and after possible Pad Length field.
|
||||
*
|
||||
* This function returns 0 if it succeeds or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_PROTO
|
||||
* TODO END_HEADERS flag is not set
|
||||
*/
|
||||
int nghttp2_frame_unpack_push_promise_payload(nghttp2_push_promise *frame,
|
||||
const uint8_t *payload,
|
||||
size_t payloadlen);
|
||||
|
||||
/*
|
||||
* Packs PING frame |frame| in wire format and store it in
|
||||
* |bufs|.
|
||||
*
|
||||
* The caller must make sure that nghttp2_bufs_reset(bufs) is called
|
||||
* before calling this function.
|
||||
*
|
||||
* This function always succeeds and returns 0.
|
||||
*/
|
||||
int nghttp2_frame_pack_ping(nghttp2_bufs *bufs, nghttp2_ping *frame);
|
||||
|
||||
/*
|
||||
* Unpacks PING wire format into |frame|.
|
||||
*/
|
||||
void nghttp2_frame_unpack_ping_payload(nghttp2_ping *frame,
|
||||
const uint8_t *payload,
|
||||
size_t payloadlen);
|
||||
|
||||
/*
|
||||
* Packs GOAWAY frame |frame| in wire format and store it in |bufs|.
|
||||
* This function expands |bufs| as necessary to store frame.
|
||||
*
|
||||
* The caller must make sure that nghttp2_bufs_reset(bufs) is called
|
||||
* before calling this function.
|
||||
*
|
||||
* This function returns 0 if it succeeds or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* NGHTTP2_ERR_FRAME_SIZE_ERROR
|
||||
* The length of the frame is too large.
|
||||
*/
|
||||
int nghttp2_frame_pack_goaway(nghttp2_bufs *bufs, nghttp2_goaway *frame);
|
||||
|
||||
/*
|
||||
* Unpacks GOAWAY wire format into |frame|. The |payload| of length
|
||||
* |payloadlen| contains first 8 bytes of payload. The
|
||||
* |var_gift_payload| of length |var_gift_payloadlen| contains
|
||||
* remaining payload and its buffer is gifted to the function and then
|
||||
* |frame|. The |var_gift_payloadlen| must be freed by
|
||||
* nghttp2_frame_goaway_free().
|
||||
*/
|
||||
void nghttp2_frame_unpack_goaway_payload(nghttp2_goaway *frame,
|
||||
const uint8_t *payload,
|
||||
size_t payloadlen,
|
||||
uint8_t *var_gift_payload,
|
||||
size_t var_gift_payloadlen);
|
||||
|
||||
/*
|
||||
* Unpacks GOAWAY wire format into |frame|. This function only exists
|
||||
* for unit test. After allocating buffer for debug data, this
|
||||
* function internally calls nghttp2_frame_unpack_goaway_payload().
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
*/
|
||||
int nghttp2_frame_unpack_goaway_payload2(nghttp2_goaway *frame,
|
||||
const uint8_t *payload,
|
||||
size_t payloadlen, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Packs WINDOW_UPDATE frame |frame| in wire frame format and store it
|
||||
* in |bufs|.
|
||||
*
|
||||
* The caller must make sure that nghttp2_bufs_reset(bufs) is called
|
||||
* before calling this function.
|
||||
*
|
||||
* This function always succeeds and returns 0.
|
||||
*/
|
||||
int nghttp2_frame_pack_window_update(nghttp2_bufs *bufs,
|
||||
nghttp2_window_update *frame);
|
||||
|
||||
/*
|
||||
* Unpacks WINDOW_UPDATE frame byte sequence into |frame|.
|
||||
*/
|
||||
void nghttp2_frame_unpack_window_update_payload(nghttp2_window_update *frame,
|
||||
const uint8_t *payload,
|
||||
size_t payloadlen);
|
||||
|
||||
/*
|
||||
* Packs ALTSVC frame |frame| in wire frame format and store it in
|
||||
* |bufs|.
|
||||
*
|
||||
* The caller must make sure that nghttp2_bufs_reset(bufs) is called
|
||||
* before calling this function.
|
||||
*
|
||||
* This function always succeeds and returns 0.
|
||||
*/
|
||||
int nghttp2_frame_pack_altsvc(nghttp2_bufs *bufs, nghttp2_extension *ext);
|
||||
|
||||
/*
|
||||
* Unpacks ALTSVC wire format into |frame|. The |payload| of
|
||||
* |payloadlen| bytes contains frame payload. This function assumes
|
||||
* that frame->payload points to the nghttp2_ext_altsvc object.
|
||||
*
|
||||
* This function always succeeds and returns 0.
|
||||
*/
|
||||
void nghttp2_frame_unpack_altsvc_payload(nghttp2_extension *frame,
|
||||
size_t origin_len, uint8_t *payload,
|
||||
size_t payloadlen);
|
||||
|
||||
/*
|
||||
* Unpacks ALTSVC wire format into |frame|. This function only exists
|
||||
* for unit test. After allocating buffer for fields, this function
|
||||
* internally calls nghttp2_frame_unpack_altsvc_payload().
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* NGHTTP2_ERR_FRAME_SIZE_ERROR
|
||||
* The payload is too small.
|
||||
*/
|
||||
int nghttp2_frame_unpack_altsvc_payload2(nghttp2_extension *frame,
|
||||
const uint8_t *payload,
|
||||
size_t payloadlen, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Initializes HEADERS frame |frame| with given values. |frame| takes
|
||||
* ownership of |nva|, so caller must not free it. If |stream_id| is
|
||||
* not assigned yet, it must be -1.
|
||||
*/
|
||||
void nghttp2_frame_headers_init(nghttp2_headers *frame, uint8_t flags,
|
||||
int32_t stream_id, nghttp2_headers_category cat,
|
||||
const nghttp2_priority_spec *pri_spec,
|
||||
nghttp2_nv *nva, size_t nvlen);
|
||||
|
||||
void nghttp2_frame_headers_free(nghttp2_headers *frame, nghttp2_mem *mem);
|
||||
|
||||
void nghttp2_frame_priority_init(nghttp2_priority *frame, int32_t stream_id,
|
||||
const nghttp2_priority_spec *pri_spec);
|
||||
|
||||
void nghttp2_frame_priority_free(nghttp2_priority *frame);
|
||||
|
||||
void nghttp2_frame_rst_stream_init(nghttp2_rst_stream *frame, int32_t stream_id,
|
||||
uint32_t error_code);
|
||||
|
||||
void nghttp2_frame_rst_stream_free(nghttp2_rst_stream *frame);
|
||||
|
||||
/*
|
||||
* Initializes PUSH_PROMISE frame |frame| with given values. |frame|
|
||||
* takes ownership of |nva|, so caller must not free it.
|
||||
*/
|
||||
void nghttp2_frame_push_promise_init(nghttp2_push_promise *frame, uint8_t flags,
|
||||
int32_t stream_id,
|
||||
int32_t promised_stream_id,
|
||||
nghttp2_nv *nva, size_t nvlen);
|
||||
|
||||
void nghttp2_frame_push_promise_free(nghttp2_push_promise *frame,
|
||||
nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Initializes SETTINGS frame |frame| with given values. |frame| takes
|
||||
* ownership of |iv|, so caller must not free it. The |flags| are
|
||||
* bitwise-OR of one or more of nghttp2_settings_flag.
|
||||
*/
|
||||
void nghttp2_frame_settings_init(nghttp2_settings *frame, uint8_t flags,
|
||||
nghttp2_settings_entry *iv, size_t niv);
|
||||
|
||||
void nghttp2_frame_settings_free(nghttp2_settings *frame, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Initializes PING frame |frame| with given values. If the
|
||||
* |opqeue_data| is not NULL, it must point to 8 bytes memory region
|
||||
* of data. The data pointed by |opaque_data| is copied. It can be
|
||||
* NULL. In this case, 8 bytes NULL is used.
|
||||
*/
|
||||
void nghttp2_frame_ping_init(nghttp2_ping *frame, uint8_t flags,
|
||||
const uint8_t *opque_data);
|
||||
|
||||
void nghttp2_frame_ping_free(nghttp2_ping *frame);
|
||||
|
||||
/*
|
||||
* Initializes GOAWAY frame |frame| with given values. On success,
|
||||
* this function takes ownership of |opaque_data|, so caller must not
|
||||
* free it. If the |opaque_data_len| is 0, opaque_data could be NULL.
|
||||
*/
|
||||
void nghttp2_frame_goaway_init(nghttp2_goaway *frame, int32_t last_stream_id,
|
||||
uint32_t error_code, uint8_t *opaque_data,
|
||||
size_t opaque_data_len);
|
||||
|
||||
void nghttp2_frame_goaway_free(nghttp2_goaway *frame, nghttp2_mem *mem);
|
||||
|
||||
void nghttp2_frame_window_update_init(nghttp2_window_update *frame,
|
||||
uint8_t flags, int32_t stream_id,
|
||||
int32_t window_size_increment);
|
||||
|
||||
void nghttp2_frame_window_update_free(nghttp2_window_update *frame);
|
||||
|
||||
void nghttp2_frame_extension_init(nghttp2_extension *frame, uint8_t type,
|
||||
uint8_t flags, int32_t stream_id,
|
||||
void *payload);
|
||||
|
||||
void nghttp2_frame_extension_free(nghttp2_extension *frame);
|
||||
|
||||
/*
|
||||
* Initializes ALTSVC frame |frame| with given values. This function
|
||||
* assumes that frame->payload points to nghttp2_ext_altsvc object.
|
||||
* Also |origin| and |field_value| are allocated in single buffer,
|
||||
* starting |origin|. On success, this function takes ownership of
|
||||
* |origin|, so caller must not free it.
|
||||
*/
|
||||
void nghttp2_frame_altsvc_init(nghttp2_extension *frame, int32_t stream_id,
|
||||
uint8_t *origin, size_t origin_len,
|
||||
uint8_t *field_value, size_t field_value_len);
|
||||
|
||||
/*
|
||||
* Frees up resources under |frame|. This function does not free
|
||||
* nghttp2_ext_altsvc object pointed by frame->payload. This function
|
||||
* only frees origin pointed by nghttp2_ext_altsvc.origin. Therefore,
|
||||
* other fields must be allocated in the same buffer with origin.
|
||||
*/
|
||||
void nghttp2_frame_altsvc_free(nghttp2_extension *frame, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Returns the number of padding bytes after payload. The total
|
||||
* padding length is given in the |padlen|. The returned value does
|
||||
* not include the Pad Length field. If |padlen| is 0, this function
|
||||
* returns 0, regardless of frame->hd.flags.
|
||||
*/
|
||||
size_t nghttp2_frame_trail_padlen(nghttp2_frame *frame, size_t padlen);
|
||||
|
||||
void nghttp2_frame_data_init(nghttp2_data *frame, uint8_t flags,
|
||||
int32_t stream_id);
|
||||
|
||||
void nghttp2_frame_data_free(nghttp2_data *frame);
|
||||
|
||||
/*
|
||||
* Makes copy of |iv| and return the copy. The |niv| is the number of
|
||||
* entries in |iv|. This function returns the pointer to the copy if
|
||||
* it succeeds, or NULL.
|
||||
*/
|
||||
nghttp2_settings_entry *nghttp2_frame_iv_copy(const nghttp2_settings_entry *iv,
|
||||
size_t niv, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Sorts the |nva| in ascending order of name and value. If names are
|
||||
* equivalent, sort them by value.
|
||||
*/
|
||||
void nghttp2_nv_array_sort(nghttp2_nv *nva, size_t nvlen);
|
||||
|
||||
/*
|
||||
* Copies name/value pairs from |nva|, which contains |nvlen| pairs,
|
||||
* to |*nva_ptr|, which is dynamically allocated so that all items can
|
||||
* be stored. The resultant name and value in nghttp2_nv are
|
||||
* guaranteed to be NULL-terminated even if the input is not
|
||||
* null-terminated.
|
||||
*
|
||||
* The |*nva_ptr| must be freed using nghttp2_nv_array_del().
|
||||
*
|
||||
* This function returns 0 if it succeeds or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
*/
|
||||
int nghttp2_nv_array_copy(nghttp2_nv **nva_ptr, const nghttp2_nv *nva,
|
||||
size_t nvlen, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Returns nonzero if the name/value pair |a| equals to |b|. The name
|
||||
* is compared in case-sensitive, because we ensure that this function
|
||||
* is called after the name is lower-cased.
|
||||
*/
|
||||
int nghttp2_nv_equal(const nghttp2_nv *a, const nghttp2_nv *b);
|
||||
|
||||
/*
|
||||
* Frees |nva|.
|
||||
*/
|
||||
void nghttp2_nv_array_del(nghttp2_nv *nva, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Checks that the |iv|, which includes |niv| entries, does not have
|
||||
* invalid values.
|
||||
*
|
||||
* This function returns nonzero if it succeeds, or 0.
|
||||
*/
|
||||
int nghttp2_iv_check(const nghttp2_settings_entry *iv, size_t niv);
|
||||
|
||||
/*
|
||||
* Sets Pad Length field and flags and adjusts frame header position
|
||||
* of each buffers in |bufs|. The number of padding is given in the
|
||||
* |padlen| including Pad Length field. The |hd| is the frame header
|
||||
* for the serialized data. This function fills zeros padding region
|
||||
* unless framehd_only is nonzero.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* NGHTTP2_ERR_FRAME_SIZE_ERROR
|
||||
* The length of the resulting frame is too large.
|
||||
*/
|
||||
int nghttp2_frame_add_pad(nghttp2_bufs *bufs, nghttp2_frame_hd *hd,
|
||||
size_t padlen, int framehd_only);
|
||||
|
||||
#endif /* NGHTTP2_FRAME_H */
|
430
components/nghttp/include/nghttp2_hd.h
Normal file
430
components/nghttp/include/nghttp2_hd.h
Normal file
|
@ -0,0 +1,430 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2013 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2_HD_H
|
||||
#define NGHTTP2_HD_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
|
||||
#include "nghttp2_hd_huffman.h"
|
||||
#include "nghttp2_buf.h"
|
||||
#include "nghttp2_mem.h"
|
||||
#include "nghttp2_rcbuf.h"
|
||||
|
||||
#define NGHTTP2_HD_DEFAULT_MAX_BUFFER_SIZE NGHTTP2_DEFAULT_HEADER_TABLE_SIZE
|
||||
#define NGHTTP2_HD_ENTRY_OVERHEAD 32
|
||||
|
||||
/* The maximum length of one name/value pair. This is the sum of the
|
||||
length of name and value. This is not specified by the spec. We
|
||||
just chose the arbitrary size */
|
||||
#define NGHTTP2_HD_MAX_NV 65536
|
||||
|
||||
/* Default size of maximum table buffer size for encoder. Even if
|
||||
remote decoder notifies larger buffer size for its decoding,
|
||||
encoder only uses the memory up to this value. */
|
||||
#define NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE (1 << 12)
|
||||
|
||||
/* Exported for unit test */
|
||||
#define NGHTTP2_STATIC_TABLE_LENGTH 61
|
||||
|
||||
/* Generated by genlibtokenlookup.py */
|
||||
typedef enum {
|
||||
NGHTTP2_TOKEN__AUTHORITY = 0,
|
||||
NGHTTP2_TOKEN__METHOD = 1,
|
||||
NGHTTP2_TOKEN__PATH = 3,
|
||||
NGHTTP2_TOKEN__SCHEME = 5,
|
||||
NGHTTP2_TOKEN__STATUS = 7,
|
||||
NGHTTP2_TOKEN_ACCEPT_CHARSET = 14,
|
||||
NGHTTP2_TOKEN_ACCEPT_ENCODING = 15,
|
||||
NGHTTP2_TOKEN_ACCEPT_LANGUAGE = 16,
|
||||
NGHTTP2_TOKEN_ACCEPT_RANGES = 17,
|
||||
NGHTTP2_TOKEN_ACCEPT = 18,
|
||||
NGHTTP2_TOKEN_ACCESS_CONTROL_ALLOW_ORIGIN = 19,
|
||||
NGHTTP2_TOKEN_AGE = 20,
|
||||
NGHTTP2_TOKEN_ALLOW = 21,
|
||||
NGHTTP2_TOKEN_AUTHORIZATION = 22,
|
||||
NGHTTP2_TOKEN_CACHE_CONTROL = 23,
|
||||
NGHTTP2_TOKEN_CONTENT_DISPOSITION = 24,
|
||||
NGHTTP2_TOKEN_CONTENT_ENCODING = 25,
|
||||
NGHTTP2_TOKEN_CONTENT_LANGUAGE = 26,
|
||||
NGHTTP2_TOKEN_CONTENT_LENGTH = 27,
|
||||
NGHTTP2_TOKEN_CONTENT_LOCATION = 28,
|
||||
NGHTTP2_TOKEN_CONTENT_RANGE = 29,
|
||||
NGHTTP2_TOKEN_CONTENT_TYPE = 30,
|
||||
NGHTTP2_TOKEN_COOKIE = 31,
|
||||
NGHTTP2_TOKEN_DATE = 32,
|
||||
NGHTTP2_TOKEN_ETAG = 33,
|
||||
NGHTTP2_TOKEN_EXPECT = 34,
|
||||
NGHTTP2_TOKEN_EXPIRES = 35,
|
||||
NGHTTP2_TOKEN_FROM = 36,
|
||||
NGHTTP2_TOKEN_HOST = 37,
|
||||
NGHTTP2_TOKEN_IF_MATCH = 38,
|
||||
NGHTTP2_TOKEN_IF_MODIFIED_SINCE = 39,
|
||||
NGHTTP2_TOKEN_IF_NONE_MATCH = 40,
|
||||
NGHTTP2_TOKEN_IF_RANGE = 41,
|
||||
NGHTTP2_TOKEN_IF_UNMODIFIED_SINCE = 42,
|
||||
NGHTTP2_TOKEN_LAST_MODIFIED = 43,
|
||||
NGHTTP2_TOKEN_LINK = 44,
|
||||
NGHTTP2_TOKEN_LOCATION = 45,
|
||||
NGHTTP2_TOKEN_MAX_FORWARDS = 46,
|
||||
NGHTTP2_TOKEN_PROXY_AUTHENTICATE = 47,
|
||||
NGHTTP2_TOKEN_PROXY_AUTHORIZATION = 48,
|
||||
NGHTTP2_TOKEN_RANGE = 49,
|
||||
NGHTTP2_TOKEN_REFERER = 50,
|
||||
NGHTTP2_TOKEN_REFRESH = 51,
|
||||
NGHTTP2_TOKEN_RETRY_AFTER = 52,
|
||||
NGHTTP2_TOKEN_SERVER = 53,
|
||||
NGHTTP2_TOKEN_SET_COOKIE = 54,
|
||||
NGHTTP2_TOKEN_STRICT_TRANSPORT_SECURITY = 55,
|
||||
NGHTTP2_TOKEN_TRANSFER_ENCODING = 56,
|
||||
NGHTTP2_TOKEN_USER_AGENT = 57,
|
||||
NGHTTP2_TOKEN_VARY = 58,
|
||||
NGHTTP2_TOKEN_VIA = 59,
|
||||
NGHTTP2_TOKEN_WWW_AUTHENTICATE = 60,
|
||||
NGHTTP2_TOKEN_TE,
|
||||
NGHTTP2_TOKEN_CONNECTION,
|
||||
NGHTTP2_TOKEN_KEEP_ALIVE,
|
||||
NGHTTP2_TOKEN_PROXY_CONNECTION,
|
||||
NGHTTP2_TOKEN_UPGRADE,
|
||||
} nghttp2_token;
|
||||
|
||||
struct nghttp2_hd_entry;
|
||||
typedef struct nghttp2_hd_entry nghttp2_hd_entry;
|
||||
|
||||
typedef struct {
|
||||
/* The buffer containing header field name. NULL-termination is
|
||||
guaranteed. */
|
||||
nghttp2_rcbuf *name;
|
||||
/* The buffer containing header field value. NULL-termination is
|
||||
guaranteed. */
|
||||
nghttp2_rcbuf *value;
|
||||
/* nghttp2_token value for name. It could be -1 if we have no token
|
||||
for that header field name. */
|
||||
int32_t token;
|
||||
/* Bitwise OR of one or more of nghttp2_nv_flag. */
|
||||
uint8_t flags;
|
||||
} nghttp2_hd_nv;
|
||||
|
||||
struct nghttp2_hd_entry {
|
||||
/* The header field name/value pair */
|
||||
nghttp2_hd_nv nv;
|
||||
/* This is solely for nghttp2_hd_{deflate,inflate}_get_table_entry
|
||||
APIs to keep backward compatibility. */
|
||||
nghttp2_nv cnv;
|
||||
/* The next entry which shares same bucket in hash table. */
|
||||
nghttp2_hd_entry *next;
|
||||
/* The sequence number. We will increment it by one whenever we
|
||||
store nghttp2_hd_entry to dynamic header table. */
|
||||
uint32_t seq;
|
||||
/* The hash value for header name (nv.name). */
|
||||
uint32_t hash;
|
||||
};
|
||||
|
||||
/* The entry used for static header table. */
|
||||
typedef struct {
|
||||
nghttp2_rcbuf name;
|
||||
nghttp2_rcbuf value;
|
||||
nghttp2_nv cnv;
|
||||
int32_t token;
|
||||
uint32_t hash;
|
||||
} nghttp2_hd_static_entry;
|
||||
|
||||
typedef struct {
|
||||
nghttp2_hd_entry **buffer;
|
||||
size_t mask;
|
||||
size_t first;
|
||||
size_t len;
|
||||
} nghttp2_hd_ringbuf;
|
||||
|
||||
typedef enum {
|
||||
NGHTTP2_HD_OPCODE_NONE,
|
||||
NGHTTP2_HD_OPCODE_INDEXED,
|
||||
NGHTTP2_HD_OPCODE_NEWNAME,
|
||||
NGHTTP2_HD_OPCODE_INDNAME
|
||||
} nghttp2_hd_opcode;
|
||||
|
||||
typedef enum {
|
||||
NGHTTP2_HD_STATE_EXPECT_TABLE_SIZE,
|
||||
NGHTTP2_HD_STATE_INFLATE_START,
|
||||
NGHTTP2_HD_STATE_OPCODE,
|
||||
NGHTTP2_HD_STATE_READ_TABLE_SIZE,
|
||||
NGHTTP2_HD_STATE_READ_INDEX,
|
||||
NGHTTP2_HD_STATE_NEWNAME_CHECK_NAMELEN,
|
||||
NGHTTP2_HD_STATE_NEWNAME_READ_NAMELEN,
|
||||
NGHTTP2_HD_STATE_NEWNAME_READ_NAMEHUFF,
|
||||
NGHTTP2_HD_STATE_NEWNAME_READ_NAME,
|
||||
NGHTTP2_HD_STATE_CHECK_VALUELEN,
|
||||
NGHTTP2_HD_STATE_READ_VALUELEN,
|
||||
NGHTTP2_HD_STATE_READ_VALUEHUFF,
|
||||
NGHTTP2_HD_STATE_READ_VALUE
|
||||
} nghttp2_hd_inflate_state;
|
||||
|
||||
typedef enum {
|
||||
NGHTTP2_HD_WITH_INDEXING,
|
||||
NGHTTP2_HD_WITHOUT_INDEXING,
|
||||
NGHTTP2_HD_NEVER_INDEXING
|
||||
} nghttp2_hd_indexing_mode;
|
||||
|
||||
typedef struct {
|
||||
/* dynamic header table */
|
||||
nghttp2_hd_ringbuf hd_table;
|
||||
/* Memory allocator */
|
||||
nghttp2_mem *mem;
|
||||
/* Abstract buffer size of hd_table as described in the spec. This
|
||||
is the sum of length of name/value in hd_table +
|
||||
NGHTTP2_HD_ENTRY_OVERHEAD bytes overhead per each entry. */
|
||||
size_t hd_table_bufsize;
|
||||
/* The effective header table size. */
|
||||
size_t hd_table_bufsize_max;
|
||||
/* Next sequence number for nghttp2_hd_entry */
|
||||
uint32_t next_seq;
|
||||
/* If inflate/deflate error occurred, this value is set to 1 and
|
||||
further invocation of inflate/deflate will fail with
|
||||
NGHTTP2_ERR_HEADER_COMP. */
|
||||
uint8_t bad;
|
||||
} nghttp2_hd_context;
|
||||
|
||||
#define HD_MAP_SIZE 128
|
||||
|
||||
typedef struct { nghttp2_hd_entry *table[HD_MAP_SIZE]; } nghttp2_hd_map;
|
||||
|
||||
struct nghttp2_hd_deflater {
|
||||
nghttp2_hd_context ctx;
|
||||
nghttp2_hd_map map;
|
||||
/* The upper limit of the header table size the deflater accepts. */
|
||||
size_t deflate_hd_table_bufsize_max;
|
||||
/* Minimum header table size notified in the next context update */
|
||||
size_t min_hd_table_bufsize_max;
|
||||
/* If nonzero, send header table size using encoding context update
|
||||
in the next deflate process */
|
||||
uint8_t notify_table_size_change;
|
||||
};
|
||||
|
||||
struct nghttp2_hd_inflater {
|
||||
nghttp2_hd_context ctx;
|
||||
/* Stores current state of huffman decoding */
|
||||
nghttp2_hd_huff_decode_context huff_decode_ctx;
|
||||
/* header buffer */
|
||||
nghttp2_buf namebuf, valuebuf;
|
||||
nghttp2_rcbuf *namercbuf, *valuercbuf;
|
||||
/* Pointer to the name/value pair which are used in the current
|
||||
header emission. */
|
||||
nghttp2_rcbuf *nv_name_keep, *nv_value_keep;
|
||||
/* The number of bytes to read */
|
||||
size_t left;
|
||||
/* The index in indexed repr or indexed name */
|
||||
size_t index;
|
||||
/* The maximum header table size the inflater supports. This is the
|
||||
same value transmitted in SETTINGS_HEADER_TABLE_SIZE */
|
||||
size_t settings_hd_table_bufsize_max;
|
||||
/* Minimum header table size set by nghttp2_hd_inflate_change_table_size */
|
||||
size_t min_hd_table_bufsize_max;
|
||||
/* The number of next shift to decode integer */
|
||||
size_t shift;
|
||||
nghttp2_hd_opcode opcode;
|
||||
nghttp2_hd_inflate_state state;
|
||||
/* nonzero if string is huffman encoded */
|
||||
uint8_t huffman_encoded;
|
||||
/* nonzero if deflater requires that current entry is indexed */
|
||||
uint8_t index_required;
|
||||
/* nonzero if deflater requires that current entry must not be
|
||||
indexed */
|
||||
uint8_t no_index;
|
||||
};
|
||||
|
||||
/*
|
||||
* Initializes the |ent| members. The reference counts of nv->name
|
||||
* and nv->value are increased by one for each.
|
||||
*/
|
||||
void nghttp2_hd_entry_init(nghttp2_hd_entry *ent, nghttp2_hd_nv *nv);
|
||||
|
||||
/*
|
||||
* This function decreases the reference counts of nv->name and
|
||||
* nv->value.
|
||||
*/
|
||||
void nghttp2_hd_entry_free(nghttp2_hd_entry *ent);
|
||||
|
||||
/*
|
||||
* Initializes |deflater| for deflating name/values pairs.
|
||||
*
|
||||
* The encoder only uses up to
|
||||
* NGHTTP2_HD_DEFAULT_MAX_DEFLATE_BUFFER_SIZE bytes for header table
|
||||
* even if the larger value is specified later in
|
||||
* nghttp2_hd_change_table_size().
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
*/
|
||||
int nghttp2_hd_deflate_init(nghttp2_hd_deflater *deflater, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Initializes |deflater| for deflating name/values pairs.
|
||||
*
|
||||
* The encoder only uses up to |deflate_hd_table_bufsize_max| bytes
|
||||
* for header table even if the larger value is specified later in
|
||||
* nghttp2_hd_change_table_size().
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
*/
|
||||
int nghttp2_hd_deflate_init2(nghttp2_hd_deflater *deflater,
|
||||
size_t deflate_hd_table_bufsize_max,
|
||||
nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Deallocates any resources allocated for |deflater|.
|
||||
*/
|
||||
void nghttp2_hd_deflate_free(nghttp2_hd_deflater *deflater);
|
||||
|
||||
/*
|
||||
* Deflates the |nva|, which has the |nvlen| name/value pairs, into
|
||||
* the |bufs|.
|
||||
*
|
||||
* This function expands |bufs| as necessary to store the result. If
|
||||
* buffers is full and the process still requires more space, this
|
||||
* funtion fails and returns NGHTTP2_ERR_HEADER_COMP.
|
||||
*
|
||||
* After this function returns, it is safe to delete the |nva|.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* NGHTTP2_ERR_HEADER_COMP
|
||||
* Deflation process has failed.
|
||||
* NGHTTP2_ERR_BUFFER_ERROR
|
||||
* Out of buffer space.
|
||||
*/
|
||||
int nghttp2_hd_deflate_hd_bufs(nghttp2_hd_deflater *deflater,
|
||||
nghttp2_bufs *bufs, const nghttp2_nv *nva,
|
||||
size_t nvlen);
|
||||
|
||||
/*
|
||||
* Initializes |inflater| for inflating name/values pairs.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* :enum:`NGHTTP2_ERR_NOMEM`
|
||||
* Out of memory.
|
||||
*/
|
||||
int nghttp2_hd_inflate_init(nghttp2_hd_inflater *inflater, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Deallocates any resources allocated for |inflater|.
|
||||
*/
|
||||
void nghttp2_hd_inflate_free(nghttp2_hd_inflater *inflater);
|
||||
|
||||
/*
|
||||
* Similar to nghttp2_hd_inflate_hd(), but this takes nghttp2_hd_nv
|
||||
* instead of nghttp2_nv as output parameter |nv_out|. Other than
|
||||
* that return values and semantics are the same as
|
||||
* nghttp2_hd_inflate_hd().
|
||||
*/
|
||||
ssize_t nghttp2_hd_inflate_hd_nv(nghttp2_hd_inflater *inflater,
|
||||
nghttp2_hd_nv *nv_out, int *inflate_flags,
|
||||
const uint8_t *in, size_t inlen, int in_final);
|
||||
|
||||
/* For unittesting purpose */
|
||||
int nghttp2_hd_emit_indname_block(nghttp2_bufs *bufs, size_t index,
|
||||
nghttp2_nv *nv, int indexing_mode);
|
||||
|
||||
/* For unittesting purpose */
|
||||
int nghttp2_hd_emit_newname_block(nghttp2_bufs *bufs, nghttp2_nv *nv,
|
||||
int indexing_mode);
|
||||
|
||||
/* For unittesting purpose */
|
||||
int nghttp2_hd_emit_table_size(nghttp2_bufs *bufs, size_t table_size);
|
||||
|
||||
/* For unittesting purpose */
|
||||
nghttp2_hd_nv nghttp2_hd_table_get(nghttp2_hd_context *context, size_t index);
|
||||
|
||||
/* For unittesting purpose */
|
||||
ssize_t nghttp2_hd_decode_length(uint32_t *res, size_t *shift_ptr, int *final,
|
||||
uint32_t initial, size_t shift, uint8_t *in,
|
||||
uint8_t *last, size_t prefix);
|
||||
|
||||
/* Huffman encoding/decoding functions */
|
||||
|
||||
/*
|
||||
* Counts the required bytes to encode |src| with length |len|.
|
||||
*
|
||||
* This function returns the number of required bytes to encode given
|
||||
* data, including padding of prefix of terminal symbol code. This
|
||||
* function always succeeds.
|
||||
*/
|
||||
size_t nghttp2_hd_huff_encode_count(const uint8_t *src, size_t len);
|
||||
|
||||
/*
|
||||
* Encodes the given data |src| with length |srclen| to the |bufs|.
|
||||
* This function expands extra buffers in |bufs| if necessary.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* NGHTTP2_ERR_BUFFER_ERROR
|
||||
* Out of buffer space.
|
||||
*/
|
||||
int nghttp2_hd_huff_encode(nghttp2_bufs *bufs, const uint8_t *src,
|
||||
size_t srclen);
|
||||
|
||||
void nghttp2_hd_huff_decode_context_init(nghttp2_hd_huff_decode_context *ctx);
|
||||
|
||||
/*
|
||||
* Decodes the given data |src| with length |srclen|. The |ctx| must
|
||||
* be initialized by nghttp2_hd_huff_decode_context_init(). The result
|
||||
* will be written to |buf|. This function assumes that |buf| has the
|
||||
* enough room to store the decoded byte string.
|
||||
*
|
||||
* The caller must set the |final| to nonzero if the given input is
|
||||
* the final block.
|
||||
*
|
||||
* This function returns the number of read bytes from the |in|.
|
||||
*
|
||||
* If this function fails, it returns one of the following negative
|
||||
* return codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory.
|
||||
* NGHTTP2_ERR_HEADER_COMP
|
||||
* Decoding process has failed.
|
||||
*/
|
||||
ssize_t nghttp2_hd_huff_decode(nghttp2_hd_huff_decode_context *ctx,
|
||||
nghttp2_buf *buf, const uint8_t *src,
|
||||
size_t srclen, int final);
|
||||
|
||||
#endif /* NGHTTP2_HD_H */
|
77
components/nghttp/include/nghttp2_hd_huffman.h
Normal file
77
components/nghttp/include/nghttp2_hd_huffman.h
Normal file
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2013 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2_HD_HUFFMAN_H
|
||||
#define NGHTTP2_HD_HUFFMAN_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
|
||||
typedef enum {
|
||||
/* FSA accepts this state as the end of huffman encoding
|
||||
sequence. */
|
||||
NGHTTP2_HUFF_ACCEPTED = 1,
|
||||
/* This state emits symbol */
|
||||
NGHTTP2_HUFF_SYM = (1 << 1),
|
||||
/* If state machine reaches this state, decoding fails. */
|
||||
NGHTTP2_HUFF_FAIL = (1 << 2)
|
||||
} nghttp2_huff_decode_flag;
|
||||
|
||||
typedef struct {
|
||||
/* huffman decoding state, which is actually the node ID of internal
|
||||
huffman tree. We have 257 leaf nodes, but they are identical to
|
||||
root node other than emitting a symbol, so we have 256 internal
|
||||
nodes [1..255], inclusive. */
|
||||
uint8_t state;
|
||||
/* bitwise OR of zero or more of the nghttp2_huff_decode_flag */
|
||||
uint8_t flags;
|
||||
/* symbol if NGHTTP2_HUFF_SYM flag set */
|
||||
uint8_t sym;
|
||||
} nghttp2_huff_decode;
|
||||
|
||||
typedef nghttp2_huff_decode huff_decode_table_type[16];
|
||||
|
||||
typedef struct {
|
||||
/* Current huffman decoding state. We stripped leaf nodes, so the
|
||||
value range is [0..255], inclusive. */
|
||||
uint8_t state;
|
||||
/* nonzero if we can say that the decoding process succeeds at this
|
||||
state */
|
||||
uint8_t accept;
|
||||
} nghttp2_hd_huff_decode_context;
|
||||
|
||||
typedef struct {
|
||||
/* The number of bits in this code */
|
||||
uint32_t nbits;
|
||||
/* Huffman code aligned to LSB */
|
||||
uint32_t code;
|
||||
} nghttp2_huff_sym;
|
||||
|
||||
extern const nghttp2_huff_sym huff_sym_table[];
|
||||
extern const nghttp2_huff_decode huff_decode_table[][16];
|
||||
|
||||
#endif /* NGHTTP2_HD_HUFFMAN_H */
|
122
components/nghttp/include/nghttp2_helper.h
Normal file
122
components/nghttp/include/nghttp2_helper.h
Normal file
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2012 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2_HELPER_H
|
||||
#define NGHTTP2_HELPER_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <string.h>
|
||||
#include <stddef.h>
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
#include "nghttp2_mem.h"
|
||||
|
||||
#define nghttp2_min(A, B) ((A) < (B) ? (A) : (B))
|
||||
#define nghttp2_max(A, B) ((A) > (B) ? (A) : (B))
|
||||
|
||||
#define lstreq(A, B, N) ((sizeof((A)) - 1) == (N) && memcmp((A), (B), (N)) == 0)
|
||||
|
||||
#define nghttp2_struct_of(ptr, type, member) \
|
||||
((type *)(void *)((char *)(ptr)-offsetof(type, member)))
|
||||
|
||||
/*
|
||||
* Copies 2 byte unsigned integer |n| in host byte order to |buf| in
|
||||
* network byte order.
|
||||
*/
|
||||
void nghttp2_put_uint16be(uint8_t *buf, uint16_t n);
|
||||
|
||||
/*
|
||||
* Copies 4 byte unsigned integer |n| in host byte order to |buf| in
|
||||
* network byte order.
|
||||
*/
|
||||
void nghttp2_put_uint32be(uint8_t *buf, uint32_t n);
|
||||
|
||||
/*
|
||||
* Retrieves 2 byte unsigned integer stored in |data| in network byte
|
||||
* order and returns it in host byte order.
|
||||
*/
|
||||
uint16_t nghttp2_get_uint16(const uint8_t *data);
|
||||
|
||||
/*
|
||||
* Retrieves 4 byte unsigned integer stored in |data| in network byte
|
||||
* order and returns it in host byte order.
|
||||
*/
|
||||
uint32_t nghttp2_get_uint32(const uint8_t *data);
|
||||
|
||||
void nghttp2_downcase(uint8_t *s, size_t len);
|
||||
|
||||
/*
|
||||
* Adjusts |*local_window_size_ptr|, |*recv_window_size_ptr|,
|
||||
* |*recv_reduction_ptr| with |*delta_ptr| which is the
|
||||
* WINDOW_UPDATE's window_size_increment sent from local side. If
|
||||
* |delta| is strictly larger than |*recv_window_size_ptr|,
|
||||
* |*local_window_size_ptr| is increased by delta -
|
||||
* *recv_window_size_ptr. If |delta| is negative,
|
||||
* |*local_window_size_ptr| is decreased by delta.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_FLOW_CONTROL
|
||||
* local_window_size overflow or gets negative.
|
||||
*/
|
||||
int nghttp2_adjust_local_window_size(int32_t *local_window_size_ptr,
|
||||
int32_t *recv_window_size_ptr,
|
||||
int32_t *recv_reduction_ptr,
|
||||
int32_t *delta_ptr);
|
||||
|
||||
/*
|
||||
* This function works like nghttp2_adjust_local_window_size(). The
|
||||
* difference is that this function assumes *delta_ptr >= 0, and
|
||||
* *recv_window_size_ptr is not decreased by *delta_ptr.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_FLOW_CONTROL
|
||||
* local_window_size overflow or gets negative.
|
||||
*/
|
||||
int nghttp2_increase_local_window_size(int32_t *local_window_size_ptr,
|
||||
int32_t *recv_window_size_ptr,
|
||||
int32_t *recv_reduction_ptr,
|
||||
int32_t *delta_ptr);
|
||||
|
||||
/*
|
||||
* Returns non-zero if the function decided that WINDOW_UPDATE should
|
||||
* be sent.
|
||||
*/
|
||||
int nghttp2_should_send_window_update(int32_t local_window_size,
|
||||
int32_t recv_window_size);
|
||||
|
||||
/*
|
||||
* Copies the buffer |src| of length |len| to the destination pointed
|
||||
* by the |dest|, assuming that the |dest| is at lest |len| bytes long
|
||||
* . Returns dest + len.
|
||||
*/
|
||||
uint8_t *nghttp2_cpymem(uint8_t *dest, const void *src, size_t len);
|
||||
|
||||
#endif /* NGHTTP2_HELPER_H */
|
97
components/nghttp/include/nghttp2_http.h
Normal file
97
components/nghttp/include/nghttp2_http.h
Normal file
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2015 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2_HTTP_H
|
||||
#define NGHTTP2_HTTP_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
#include "nghttp2_session.h"
|
||||
#include "nghttp2_stream.h"
|
||||
|
||||
/*
|
||||
* This function is called when HTTP header field |nv| in |frame| is
|
||||
* received for |stream|. This function will validate |nv| against
|
||||
* the current state of stream.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_HTTP_HEADER
|
||||
* Invalid HTTP header field was received.
|
||||
* NGHTTP2_ERR_IGN_HTTP_HEADER
|
||||
* Invalid HTTP header field was received but it can be treated as
|
||||
* if it was not received because of compatibility reasons.
|
||||
*/
|
||||
int nghttp2_http_on_header(nghttp2_session *session, nghttp2_stream *stream,
|
||||
nghttp2_frame *frame, nghttp2_hd_nv *nv,
|
||||
int trailer);
|
||||
|
||||
/*
|
||||
* This function is called when request header is received. This
|
||||
* function performs validation and returns 0 if it succeeds, or -1.
|
||||
*/
|
||||
int nghttp2_http_on_request_headers(nghttp2_stream *stream,
|
||||
nghttp2_frame *frame);
|
||||
|
||||
/*
|
||||
* This function is called when response header is received. This
|
||||
* function performs validation and returns 0 if it succeeds, or -1.
|
||||
*/
|
||||
int nghttp2_http_on_response_headers(nghttp2_stream *stream);
|
||||
|
||||
/*
|
||||
* This function is called trailer header (for both request and
|
||||
* response) is received. This function performs validation and
|
||||
* returns 0 if it succeeds, or -1.
|
||||
*/
|
||||
int nghttp2_http_on_trailer_headers(nghttp2_stream *stream,
|
||||
nghttp2_frame *frame);
|
||||
|
||||
/*
|
||||
* This function is called when END_STREAM flag is seen in incoming
|
||||
* frame. This function performs validation and returns 0 if it
|
||||
* succeeds, or -1.
|
||||
*/
|
||||
int nghttp2_http_on_remote_end_stream(nghttp2_stream *stream);
|
||||
|
||||
/*
|
||||
* This function is called when chunk of data is received. This
|
||||
* function performs validation and returns 0 if it succeeds, or -1.
|
||||
*/
|
||||
int nghttp2_http_on_data_chunk(nghttp2_stream *stream, size_t n);
|
||||
|
||||
/*
|
||||
* This function inspects header field in |frame| and records its
|
||||
* method in stream->http_flags. If frame->hd.type is neither
|
||||
* NGHTTP2_HEADERS nor NGHTTP2_PUSH_PROMISE, this function does
|
||||
* nothing.
|
||||
*/
|
||||
void nghttp2_http_record_request_method(nghttp2_stream *stream,
|
||||
nghttp2_frame *frame);
|
||||
|
||||
#endif /* NGHTTP2_HTTP_H */
|
58
components/nghttp/include/nghttp2_int.h
Normal file
58
components/nghttp/include/nghttp2_int.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2012 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2_INT_H
|
||||
#define NGHTTP2_INT_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
/* Macros, types and constants for internal use */
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
#define DEBUGF(x) x
|
||||
#else
|
||||
#define DEBUGF(x) \
|
||||
do { \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
/* "less" function, return nonzero if |lhs| is less than |rhs|. */
|
||||
typedef int (*nghttp2_less)(const void *lhs, const void *rhs);
|
||||
|
||||
/* Internal error code. They must be in the range [-499, -100],
|
||||
inclusive. */
|
||||
typedef enum {
|
||||
NGHTTP2_ERR_CREDENTIAL_PENDING = -101,
|
||||
NGHTTP2_ERR_IGN_HEADER_BLOCK = -103,
|
||||
NGHTTP2_ERR_IGN_PAYLOAD = -104,
|
||||
/*
|
||||
* Invalid HTTP header field was received but it can be treated as
|
||||
* if it was not received because of compatibility reasons.
|
||||
*/
|
||||
NGHTTP2_ERR_IGN_HTTP_HEADER = -105
|
||||
} nghttp2_internal_error;
|
||||
|
||||
#endif /* NGHTTP2_INT_H */
|
144
components/nghttp/include/nghttp2_map.h
Normal file
144
components/nghttp/include/nghttp2_map.h
Normal file
|
@ -0,0 +1,144 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2012 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2_MAP_H
|
||||
#define NGHTTP2_MAP_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
#include "nghttp2_int.h"
|
||||
#include "nghttp2_mem.h"
|
||||
|
||||
/* Implementation of unordered map */
|
||||
|
||||
typedef int32_t key_type;
|
||||
|
||||
typedef struct nghttp2_map_entry {
|
||||
struct nghttp2_map_entry *next;
|
||||
key_type key;
|
||||
#if SIZEOF_INT_P == 4
|
||||
/* we requires 8 bytes aligment */
|
||||
int64_t pad;
|
||||
#endif
|
||||
} nghttp2_map_entry;
|
||||
|
||||
typedef struct {
|
||||
nghttp2_map_entry **table;
|
||||
nghttp2_mem *mem;
|
||||
size_t size;
|
||||
uint32_t tablelen;
|
||||
} nghttp2_map;
|
||||
|
||||
/*
|
||||
* Initializes the map |map|.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory
|
||||
*/
|
||||
int nghttp2_map_init(nghttp2_map *map, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* Deallocates any resources allocated for |map|. The stored entries
|
||||
* are not freed by this function. Use nghttp2_map_each_free() to free
|
||||
* each entries.
|
||||
*/
|
||||
void nghttp2_map_free(nghttp2_map *map);
|
||||
|
||||
/*
|
||||
* Deallocates each entries using |func| function and any resources
|
||||
* allocated for |map|. The |func| function is responsible for freeing
|
||||
* given the |entry| object. The |ptr| will be passed to the |func| as
|
||||
* send argument. The return value of the |func| will be ignored.
|
||||
*/
|
||||
void nghttp2_map_each_free(nghttp2_map *map,
|
||||
int (*func)(nghttp2_map_entry *entry, void *ptr),
|
||||
void *ptr);
|
||||
|
||||
/*
|
||||
* Initializes the |entry| with the |key|. All entries to be inserted
|
||||
* to the map must be initialized with this function.
|
||||
*/
|
||||
void nghttp2_map_entry_init(nghttp2_map_entry *entry, key_type key);
|
||||
|
||||
/*
|
||||
* Inserts the new |entry| with the key |entry->key| to the map |map|.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_INVALID_ARGUMENT
|
||||
* The item associated by |key| already exists.
|
||||
* NGHTTP2_ERR_NOMEM
|
||||
* Out of memory
|
||||
*/
|
||||
int nghttp2_map_insert(nghttp2_map *map, nghttp2_map_entry *entry);
|
||||
|
||||
/*
|
||||
* Returns the entry associated by the key |key|. If there is no such
|
||||
* entry, this function returns NULL.
|
||||
*/
|
||||
nghttp2_map_entry *nghttp2_map_find(nghttp2_map *map, key_type key);
|
||||
|
||||
/*
|
||||
* Removes the entry associated by the key |key| from the |map|. The
|
||||
* removed entry is not freed by this function.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
* NGHTTP2_ERR_INVALID_ARGUMENT
|
||||
* The entry associated by |key| does not exist.
|
||||
*/
|
||||
int nghttp2_map_remove(nghttp2_map *map, key_type key);
|
||||
|
||||
/*
|
||||
* Returns the number of items stored in the map |map|.
|
||||
*/
|
||||
size_t nghttp2_map_size(nghttp2_map *map);
|
||||
|
||||
/*
|
||||
* Applies the function |func| to each entry in the |map| with the
|
||||
* optional user supplied pointer |ptr|.
|
||||
*
|
||||
* If the |func| returns 0, this function calls the |func| with the
|
||||
* next entry. If the |func| returns nonzero, it will not call the
|
||||
* |func| for further entries and return the return value of the
|
||||
* |func| immediately. Thus, this function returns 0 if all the
|
||||
* invocations of the |func| return 0, or nonzero value which the last
|
||||
* invocation of |func| returns.
|
||||
*
|
||||
* Don't use this function to free each entry. Use
|
||||
* nghttp2_map_each_free() instead.
|
||||
*/
|
||||
int nghttp2_map_each(nghttp2_map *map,
|
||||
int (*func)(nghttp2_map_entry *entry, void *ptr),
|
||||
void *ptr);
|
||||
|
||||
#endif /* NGHTTP2_MAP_H */
|
45
components/nghttp/include/nghttp2_mem.h
Normal file
45
components/nghttp/include/nghttp2_mem.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2014 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2_MEM_H
|
||||
#define NGHTTP2_MEM_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
|
||||
/* The default, system standard memory allocator */
|
||||
nghttp2_mem *nghttp2_mem_default(void);
|
||||
|
||||
/* Convenient wrapper functions to call allocator function in
|
||||
|mem|. */
|
||||
void *nghttp2_mem_malloc(nghttp2_mem *mem, size_t size);
|
||||
void nghttp2_mem_free(nghttp2_mem *mem, void *ptr);
|
||||
void nghttp2_mem_free2(nghttp2_free free_func, void *ptr, void *mem_user_data);
|
||||
void *nghttp2_mem_calloc(nghttp2_mem *mem, size_t nmemb, size_t size);
|
||||
void *nghttp2_mem_realloc(nghttp2_mem *mem, void *ptr, size_t size);
|
||||
|
||||
#endif /* NGHTTP2_MEM_H */
|
91
components/nghttp/include/nghttp2_net.h
Normal file
91
components/nghttp/include/nghttp2_net.h
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2012 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2_NET_H
|
||||
#define NGHTTP2_NET_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#ifdef HAVE_ARPA_INET_H
|
||||
#include <arpa/inet.h>
|
||||
#endif /* HAVE_ARPA_INET_H */
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#endif /* HAVE_NETINET_IN_H */
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
|
||||
#if defined(WIN32)
|
||||
/* Windows requires ws2_32 library for ntonl family functions. We
|
||||
define inline functions for those function so that we don't have
|
||||
dependeny on that lib. */
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define STIN static __inline
|
||||
#else
|
||||
#define STIN static inline
|
||||
#endif
|
||||
|
||||
STIN uint32_t htonl(uint32_t hostlong) {
|
||||
uint32_t res;
|
||||
unsigned char *p = (unsigned char *)&res;
|
||||
*p++ = hostlong >> 24;
|
||||
*p++ = (hostlong >> 16) & 0xffu;
|
||||
*p++ = (hostlong >> 8) & 0xffu;
|
||||
*p = hostlong & 0xffu;
|
||||
return res;
|
||||
}
|
||||
|
||||
STIN uint16_t htons(uint16_t hostshort) {
|
||||
uint16_t res;
|
||||
unsigned char *p = (unsigned char *)&res;
|
||||
*p++ = hostshort >> 8;
|
||||
*p = hostshort & 0xffu;
|
||||
return res;
|
||||
}
|
||||
|
||||
STIN uint32_t ntohl(uint32_t netlong) {
|
||||
uint32_t res;
|
||||
unsigned char *p = (unsigned char *)&netlong;
|
||||
res = *p++ << 24;
|
||||
res += *p++ << 16;
|
||||
res += *p++ << 8;
|
||||
res += *p;
|
||||
return res;
|
||||
}
|
||||
|
||||
STIN uint16_t ntohs(uint16_t netshort) {
|
||||
uint16_t res;
|
||||
unsigned char *p = (unsigned char *)&netshort;
|
||||
res = *p++ << 8;
|
||||
res += *p;
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif /* WIN32 */
|
||||
|
||||
#endif /* NGHTTP2_NET_H */
|
34
components/nghttp/include/nghttp2_npn.h
Normal file
34
components/nghttp/include/nghttp2_npn.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2012 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2_NPN_H
|
||||
#define NGHTTP2_NPN_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
|
||||
#endif /* NGHTTP2_NPN_H */
|
116
components/nghttp/include/nghttp2_option.h
Normal file
116
components/nghttp/include/nghttp2_option.h
Normal file
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2014 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2_OPTION_H
|
||||
#define NGHTTP2_OPTION_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
|
||||
/**
|
||||
* Configuration options
|
||||
*/
|
||||
typedef enum {
|
||||
/**
|
||||
* This option prevents the library from sending WINDOW_UPDATE for a
|
||||
* connection automatically. If this option is set to nonzero, the
|
||||
* library won't send WINDOW_UPDATE for DATA until application calls
|
||||
* nghttp2_session_consume() to indicate the amount of consumed
|
||||
* DATA. By default, this option is set to zero.
|
||||
*/
|
||||
NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE = 1,
|
||||
/**
|
||||
* This option sets the SETTINGS_MAX_CONCURRENT_STREAMS value of
|
||||
* remote endpoint as if it is received in SETTINGS frame. Without
|
||||
* specifying this option, before the local endpoint receives
|
||||
* SETTINGS_MAX_CONCURRENT_STREAMS in SETTINGS frame from remote
|
||||
* endpoint, SETTINGS_MAX_CONCURRENT_STREAMS is unlimited. This may
|
||||
* cause problem if local endpoint submits lots of requests
|
||||
* initially and sending them at once to the remote peer may lead to
|
||||
* the rejection of some requests. Specifying this option to the
|
||||
* sensible value, say 100, may avoid this kind of issue. This value
|
||||
* will be overwritten if the local endpoint receives
|
||||
* SETTINGS_MAX_CONCURRENT_STREAMS from the remote endpoint.
|
||||
*/
|
||||
NGHTTP2_OPT_PEER_MAX_CONCURRENT_STREAMS = 1 << 1,
|
||||
NGHTTP2_OPT_NO_RECV_CLIENT_MAGIC = 1 << 2,
|
||||
NGHTTP2_OPT_NO_HTTP_MESSAGING = 1 << 3,
|
||||
NGHTTP2_OPT_MAX_RESERVED_REMOTE_STREAMS = 1 << 4,
|
||||
NGHTTP2_OPT_USER_RECV_EXT_TYPES = 1 << 5,
|
||||
NGHTTP2_OPT_NO_AUTO_PING_ACK = 1 << 6,
|
||||
NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES = 1 << 7,
|
||||
NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH = 1 << 8,
|
||||
} nghttp2_option_flag;
|
||||
|
||||
/**
|
||||
* Struct to store option values for nghttp2_session.
|
||||
*/
|
||||
struct nghttp2_option {
|
||||
/**
|
||||
* NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH
|
||||
*/
|
||||
size_t max_send_header_block_length;
|
||||
/**
|
||||
* Bitwise OR of nghttp2_option_flag to determine that which fields
|
||||
* are specified.
|
||||
*/
|
||||
uint32_t opt_set_mask;
|
||||
/**
|
||||
* NGHTTP2_OPT_PEER_MAX_CONCURRENT_STREAMS
|
||||
*/
|
||||
uint32_t peer_max_concurrent_streams;
|
||||
/**
|
||||
* NGHTTP2_OPT_MAX_RESERVED_REMOTE_STREAMS
|
||||
*/
|
||||
uint32_t max_reserved_remote_streams;
|
||||
/**
|
||||
* NGHTTP2_OPT_BUILTIN_RECV_EXT_TYPES
|
||||
*/
|
||||
uint32_t builtin_recv_ext_types;
|
||||
/**
|
||||
* NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE
|
||||
*/
|
||||
int no_auto_window_update;
|
||||
/**
|
||||
* NGHTTP2_OPT_NO_RECV_CLIENT_MAGIC
|
||||
*/
|
||||
int no_recv_client_magic;
|
||||
/**
|
||||
* NGHTTP2_OPT_NO_HTTP_MESSAGING
|
||||
*/
|
||||
int no_http_messaging;
|
||||
/**
|
||||
* NGHTTP2_OPT_NO_AUTO_PING_ACK
|
||||
*/
|
||||
int no_auto_ping_ack;
|
||||
/**
|
||||
* NGHTTP2_OPT_USER_RECV_EXT_TYPES
|
||||
*/
|
||||
uint8_t user_recv_ext_types[32];
|
||||
};
|
||||
|
||||
#endif /* NGHTTP2_OPTION_H */
|
166
components/nghttp/include/nghttp2_outbound_item.h
Normal file
166
components/nghttp/include/nghttp2_outbound_item.h
Normal file
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
* nghttp2 - HTTP/2 C Library
|
||||
*
|
||||
* Copyright (c) 2012 Tatsuhiro Tsujikawa
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
#ifndef NGHTTP2_OUTBOUND_ITEM_H
|
||||
#define NGHTTP2_OUTBOUND_ITEM_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
||||
#include <nghttp2/nghttp2.h>
|
||||
#include "nghttp2_frame.h"
|
||||
#include "nghttp2_mem.h"
|
||||
|
||||
/* struct used for HEADERS and PUSH_PROMISE frame */
|
||||
typedef struct {
|
||||
nghttp2_data_provider data_prd;
|
||||
void *stream_user_data;
|
||||
/* error code when request HEADERS is canceled by RST_STREAM while
|
||||
it is in queue. */
|
||||
uint32_t error_code;
|
||||
/* nonzero if request HEADERS is canceled. The error code is stored
|
||||
in |error_code|. */
|
||||
uint8_t canceled;
|
||||
} nghttp2_headers_aux_data;
|
||||
|
||||
/* struct used for DATA frame */
|
||||
typedef struct {
|
||||
/**
|
||||
* The data to be sent for this DATA frame.
|
||||
*/
|
||||
nghttp2_data_provider data_prd;
|
||||
/**
|
||||
* The flags of DATA frame. We use separate flags here and
|
||||
* nghttp2_data frame. The latter contains flags actually sent to
|
||||
* peer. This |flags| may contain NGHTTP2_FLAG_END_STREAM and only
|
||||
* when |eof| becomes nonzero, flags in nghttp2_data has
|
||||
* NGHTTP2_FLAG_END_STREAM set.
|
||||
*/
|
||||
uint8_t flags;
|
||||
/**
|
||||
* The flag to indicate whether EOF was reached or not. Initially
|
||||
* |eof| is 0. It becomes 1 after all data were read.
|
||||
*/
|
||||
uint8_t eof;
|
||||
/**
|
||||
* The flag to indicate that NGHTTP2_DATA_FLAG_NO_COPY is used.
|
||||
*/
|
||||
uint8_t no_copy;
|
||||
} nghttp2_data_aux_data;
|
||||
|
||||
typedef enum {
|
||||
NGHTTP2_GOAWAY_AUX_NONE = 0x0,
|
||||
/* indicates that session should be terminated after the
|
||||
transmission of this frame. */
|
||||
NGHTTP2_GOAWAY_AUX_TERM_ON_SEND = 0x1,
|
||||
/* indicates that this GOAWAY is just a notification for graceful
|
||||
shutdown. No nghttp2_session.goaway_flags should be updated on
|
||||
the reaction to this frame. */
|
||||
NGHTTP2_GOAWAY_AUX_SHUTDOWN_NOTICE = 0x2
|
||||
} nghttp2_goaway_aux_flag;
|
||||
|
||||
/* struct used for GOAWAY frame */
|
||||
typedef struct {
|
||||
/* bitwise-OR of one or more of nghttp2_goaway_aux_flag. */
|
||||
uint8_t flags;
|
||||
} nghttp2_goaway_aux_data;
|
||||
|
||||
/* struct used for extension frame */
|
||||
typedef struct {
|
||||
/* nonzero if this extension frame is serialized by library
|
||||
function, instead of user-defined callbacks. */
|
||||
uint8_t builtin;
|
||||
} nghttp2_ext_aux_data;
|
||||
|
||||
/* Additional data which cannot be stored in nghttp2_frame struct */
|
||||
typedef union {
|
||||
nghttp2_data_aux_data data;
|
||||
nghttp2_headers_aux_data headers;
|
||||
nghttp2_goaway_aux_data goaway;
|
||||
nghttp2_ext_aux_data ext;
|
||||
} nghttp2_aux_data;
|
||||
|
||||
struct nghttp2_outbound_item;
|
||||
typedef struct nghttp2_outbound_item nghttp2_outbound_item;
|
||||
|
||||
struct nghttp2_outbound_item {
|
||||
nghttp2_frame frame;
|
||||
/* Storage for extension frame payload. frame->ext.payload points
|
||||
to this structure to avoid frequent memory allocation. */
|
||||
nghttp2_ext_frame_payload ext_frame_payload;
|
||||
nghttp2_aux_data aux_data;
|
||||
/* The priority used in priority comparion. Smaller is served
|
||||
ealier. For PING, SETTINGS and non-DATA frames (excluding
|
||||
response HEADERS frame) have dedicated cycle value defined above.
|
||||
For DATA frame, cycle is computed by taking into account of
|
||||
effective weight and frame payload length previously sent, so
|
||||
that the amount of transmission is distributed across streams
|
||||
proportional to effective weight (inside a tree). */
|
||||
uint64_t cycle;
|
||||
nghttp2_outbound_item *qnext;
|
||||
/* nonzero if this object is queued, except for DATA or HEADERS
|
||||
which are attached to stream as item. */
|
||||
uint8_t queued;
|
||||
};
|
||||
|
||||
/*
|
||||
* Initializes |item|. No memory allocation is done in this function.
|
||||
* Don't call nghttp2_outbound_item_free() until frame member is
|
||||
* initialized.
|
||||
*/
|
||||
void nghttp2_outbound_item_init(nghttp2_outbound_item *item);
|
||||
|
||||
/*
|
||||
* Deallocates resource for |item|. If |item| is NULL, this function
|
||||
* does nothing.
|
||||
*/
|
||||
void nghttp2_outbound_item_free(nghttp2_outbound_item *item, nghttp2_mem *mem);
|
||||
|
||||
/*
|
||||
* queue for nghttp2_outbound_item.
|
||||
*/
|
||||
typedef struct {
|
||||
nghttp2_outbound_item *head, *tail;
|
||||
/* number of items in this queue. */
|
||||
size_t n;
|
||||
} nghttp2_outbound_queue;
|
||||
|
||||
void nghttp2_outbound_queue_init(nghttp2_outbound_queue *q);
|
||||
|
||||
/* Pushes |item| into |q| */
|
||||
void nghttp2_outbound_queue_push(nghttp2_outbound_queue *q,
|
||||
nghttp2_outbound_item *item);
|
||||
|
||||
/* Pops |item| at the top from |q|. If |q| is empty, nothing
|
||||
happens. */
|
||||
void nghttp2_outbound_queue_pop(nghttp2_outbound_queue *q);
|
||||
|
||||
/* Returns the top item. */
|
||||
#define nghttp2_outbound_queue_top(Q) ((Q)->head)
|
||||
|
||||
/* Returns the size of the queue */
|
||||
#define nghttp2_outbound_queue_size(Q) ((Q)->n)
|
||||
|
||||
#endif /* NGHTTP2_OUTBOUND_ITEM_H */
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue