feat: init and support ws2812b.

This commit is contained in:
Ivan Li 2022-11-12 22:33:03 +08:00
commit 601bbc2346
11 changed files with 589 additions and 0 deletions

38
.devcontainer/Dockerfile Normal file
View File

@ -0,0 +1,38 @@
FROM espressif/idf
ARG DEBIAN_FRONTEND=nointeractive
RUN apt-get update \
&& apt install -y -q \
cmake \
git \
hwdata \
libglib2.0-0 \
libnuma1 \
libpixman-1-0 \
linux-tools-virtual \
&& rm -rf /var/lib/apt/lists/*
RUN update-alternatives --install /usr/local/bin/usbip usbip `ls /usr/lib/linux-tools/*/usbip | tail -n1` 20
# QEMU
ENV QEMU_REL=esp-develop-20220919
ENV QEMU_SHA256=f6565d3f0d1e463a63a7f81aec94cce62df662bd42fc7606de4b4418ed55f870
ENV QEMU_DIST=qemu-${QEMU_REL}.tar.bz2
ENV QEMU_URL=https://github.com/espressif/qemu/releases/download/${QEMU_REL}/${QEMU_DIST}
ENV LC_ALL=C.UTF-8
ENV LANG=C.UTF-8
RUN wget --no-verbose ${QEMU_URL} \
&& echo "${QEMU_SHA256} *${QEMU_DIST}" | sha256sum --check --strict - \
&& tar -xf $QEMU_DIST -C /opt \
&& rm ${QEMU_DIST}
ENV PATH=/opt/qemu/bin:${PATH}
RUN echo "source /opt/esp/idf/export.sh > /dev/null 2>&1" >> ~/.bashrc
ENTRYPOINT [ "/opt/esp/entrypoint.sh" ]
CMD ["/bin/bash"]

View File

@ -0,0 +1,29 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at:
// https://github.com/microsoft/vscode-dev-containers/tree/v0.183.0/containers/ubuntu
{
"name": "ESP-IDF QEMU",
"build": {
"dockerfile": "Dockerfile"
},
// Add the IDs of extensions you want installed when the container is created.
"extensions": [
"ms-vscode.cpptools",
"espressif.esp-idf-extension"
],
"workspaceMount": "source=${localWorkspaceFolder},target=/workspaces,type=bind",
/* the path of workspace folder to be opened after container is running
*/
"workspaceFolder": "/workspaces",
"mounts": [
"source=extensionCache,target=/root/.vscode-server/extensions,type=volume"
],
"settings": {
"terminal.integrated.defaultProfile.linux": "bash",
"idf.espIdfPath": "/opt/esp/idf",
"idf.customExtraPaths": "",
"idf.pythonBinPath": "/opt/esp/python_env/idf5.1_py3.8_env/bin/python",
"idf.toolsPath": "/opt/esp",
"idf.gitPath": "/usr/bin/git"
},
"runArgs": ["--privileged"]
}

3
.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
build/
sdkconfig
sdkconfig.old

30
.vscode/c_cpp_properties.json vendored Normal file
View File

@ -0,0 +1,30 @@
{
"configurations": [
{
"name": "ESP-IDF",
"compilerPath": "/Users/ivan/.espressif/tools/riscv32-esp-elf/esp-2021r2-patch3-8.4.0/riscv32-esp-elf/bin/riscv32-esp-elf-gcc",
"cStandard": "c11",
"cppStandard": "c++17",
"includePath": [
"${config:idf.espIdfPath}/components/**",
"${config:idf.espIdfPathWin}/components/**",
"${config:idf.espAdfPath}/components/**",
"${config:idf.espAdfPathWin}/components/**",
"${workspaceFolder}/**"
],
"browse": {
"path": [
"/Users/ivan/esp/esp-idf/components",
"${config:idf.espIdfPathWin}/components",
"/Users/ivan/esp/esp-idf/components/**",
"${config:idf.espAdfPathWin}/components/**",
"${workspaceFolder}"
],
"limitSymbolsToIncludedHeaders": false
},
"compileCommands": "${workspaceFolder}/build/compile_commands.json",
"configurationProvider": "ms-vscode.cmake-tools"
}
],
"version": 4
}

10
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,10 @@
{
"version": "0.2.0",
"configurations": [
{
"type": "espidf",
"name": "Launch",
"request": "launch"
}
]
}

15
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,15 @@
{
"C_Cpp.intelliSenseEngine": "Tag Parser",
"idf.adapterTargetName": "esp32c3",
"idf.customExtraPaths": "/Users/ivan/.espressif/tools/xtensa-esp32-elf/esp-2021r2-patch5-8.4.0/xtensa-esp32-elf/bin:/Users/ivan/.espressif/tools/xtensa-esp32s2-elf/esp-2021r2-patch5-8.4.0/xtensa-esp32s2-elf/bin:/Users/ivan/.espressif/tools/xtensa-esp32s3-elf/esp-2021r2-patch5-8.4.0/xtensa-esp32s3-elf/bin:/Users/ivan/.espressif/tools/riscv32-esp-elf/esp-2021r2-patch5-8.4.0/riscv32-esp-elf/bin:/Users/ivan/.espressif/tools/esp32ulp-elf/2.35_20220830/esp32ulp-elf/bin:/Users/ivan/.espressif/tools/cmake/3.23.1/CMake.app/Contents/bin:/Users/ivan/.espressif/tools/openocd-esp32/v0.11.0-esp32-20220706/openocd-esp32/bin:/Users/ivan/.espressif/tools/ninja/1.10.2",
"idf.customExtraVars": "{\"OPENOCD_SCRIPTS\":\"/Users/ivan/.espressif/tools/openocd-esp32/v0.11.0-esp32-20220706/openocd-esp32/share/openocd/scripts\"}",
"idf.espIdfPath": "/Users/ivan/esp/esp-idf",
"idf.openOcdConfigs": [
"board/esp32c3-builtin.cfg"
],
"idf.port": "/dev/cu.usbmodem149201",
"idf.pythonBinPath": "/Users/ivan/.espressif/python_env/idf4.4_py3.8_env/bin/python",
"idf.toolsPath": "/Users/ivan/.espressif",
"idf.gitPath": "/usr/bin/git",
"idf.flashType": "JTAG"
}

300
.vscode/tasks.json vendored Normal file
View File

@ -0,0 +1,300 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "Build - Build project",
"type": "shell",
"command": "${config:idf.pythonBinPath} ${config:idf.espIdfPath}/tools/idf.py build",
"windows": {
"command": "${config:idf.pythonBinPathWin} ${config:idf.espIdfPathWin}\\tools\\idf.py build",
"options": {
"env": {
"PATH": "${env:PATH};${config:idf.customExtraPaths}"
}
}
},
"options": {
"env": {
"PATH": "${env:PATH}:${config:idf.customExtraPaths}"
}
},
"problemMatcher": [
{
"owner": "cpp",
"fileLocation": [
"relative",
"${workspaceFolder}"
],
"pattern": {
"regexp": "^\\.\\.(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
},
{
"owner": "cpp",
"fileLocation": "absolute",
"pattern": {
"regexp": "^[^\\.](.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
}
],
"group": {
"kind": "build",
"isDefault": true
}
},
{
"label": "Set ESP-IDF Target",
"type": "shell",
"command": "${command:espIdf.setTarget}",
"problemMatcher": {
"owner": "cpp",
"fileLocation": "absolute",
"pattern": {
"regexp": "^(.*):(//d+):(//d+)://s+(warning|error)://s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
}
},
{
"label": "Clean - Clean the project",
"type": "shell",
"command": "${config:idf.pythonBinPath} ${config:idf.espIdfPath}/tools/idf.py fullclean",
"windows": {
"command": "${config:idf.pythonBinPathWin} ${config:idf.espIdfPathWin}\\tools\\idf.py fullclean",
"options": {
"env": {
"PATH": "${env:PATH};${config:idf.customExtraPaths}"
}
}
},
"options": {
"env": {
"PATH": "${env:PATH}:${config:idf.customExtraPaths}"
}
},
"problemMatcher": [
{
"owner": "cpp",
"fileLocation": [
"relative",
"${workspaceFolder}"
],
"pattern": {
"regexp": "^\\.\\.(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
},
{
"owner": "cpp",
"fileLocation": "absolute",
"pattern": {
"regexp": "^[^\\.](.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
}
]
},
{
"label": "Flash - Flash the device",
"type": "shell",
"command": "${config:idf.pythonBinPath} ${config:idf.espIdfPath}/tools/idf.py -p ${config:idf.port} -b ${config:idf.flashBaudRate} flash",
"windows": {
"command": "${config:idf.pythonBinPathWin} ${config:idf.espIdfPathWin}\\tools\\idf.py flash -p ${config:idf.portWin} -b ${config:idf.flashBaudRate}",
"options": {
"env": {
"PATH": "${env:PATH};${config:idf.customExtraPaths}"
}
}
},
"options": {
"env": {
"PATH": "${env:PATH}:${config:idf.customExtraPaths}"
}
},
"problemMatcher": [
{
"owner": "cpp",
"fileLocation": [
"relative",
"${workspaceFolder}"
],
"pattern": {
"regexp": "^\\.\\.(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
},
{
"owner": "cpp",
"fileLocation": "absolute",
"pattern": {
"regexp": "^[^\\.](.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
}
]
},
{
"label": "Monitor: Start the monitor",
"type": "shell",
"command": "${config:idf.pythonBinPath} ${config:idf.espIdfPath}/tools/idf.py -p ${config:idf.port} monitor",
"windows": {
"command": "${config:idf.pythonBinPathWin} ${config:idf.espIdfPathWin}\\tools\\idf.py -p ${config:idf.portWin} monitor",
"options": {
"env": {
"PATH": "${env:PATH};${config:idf.customExtraPaths}"
}
}
},
"options": {
"env": {
"PATH": "${env:PATH}:${config:idf.customExtraPaths}"
}
},
"problemMatcher": [
{
"owner": "cpp",
"fileLocation": [
"relative",
"${workspaceFolder}"
],
"pattern": {
"regexp": "^\\.\\.(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
},
{
"owner": "cpp",
"fileLocation": "absolute",
"pattern": {
"regexp": "^[^\\.](.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
}
],
"dependsOn": "Flash - Flash the device"
},
{
"label": "OpenOCD: Start openOCD",
"type": "shell",
"presentation": {
"echo": true,
"reveal": "never",
"focus": false,
"panel": "new"
},
"command": "openocd -s ${command:espIdf.getOpenOcdScriptValue} ${command:espIdf.getOpenOcdConfigs}",
"windows": {
"command": "openocd.exe -s ${command:espIdf.getOpenOcdScriptValue} ${command:espIdf.getOpenOcdConfigs}",
"options": {
"env": {
"PATH": "${env:PATH};${config:idf.customExtraPaths}"
}
}
},
"options": {
"env": {
"PATH": "${env:PATH}:${config:idf.customExtraPaths}"
}
},
"problemMatcher": {
"owner": "cpp",
"fileLocation": "absolute",
"pattern": {
"regexp": "^(.*):(\\d+):(\\d+):\\s+(warning|error):\\s+(.*)$",
"file": 1,
"line": 2,
"column": 3,
"severity": 4,
"message": 5
}
}
},
{
"label": "adapter",
"type": "shell",
"command": "${config:idf.pythonBinPath}",
"isBackground": true,
"options": {
"env": {
"PATH": "${env:PATH}:${config:idf.customExtraPaths}",
"PYTHONPATH": "${command:espIdf.getExtensionPath}/esp_debug_adapter/debug_adapter"
}
},
"problemMatcher": {
"background": {
"beginsPattern": "\bDEBUG_ADAPTER_STARTED\b",
"endsPattern": "DEBUG_ADAPTER_READY2CONNECT",
"activeOnStart": true
},
"pattern": {
"regexp": "(\\d+)-(\\d+)-(\\d+)\\s(\\d+):(\\d+):(\\d+),(\\d+)\\s-(.+)\\s(ERROR)",
"file": 8,
"line": 2,
"column": 3,
"severity": 4,
"message": 9
}
},
"args": [
"${command:espIdf.getExtensionPath}/esp_debug_adapter/debug_adapter_main.py",
"-e",
"${workspaceFolder}/build/${command:espIdf.getProjectName}.elf",
"-s",
"${command:espIdf.getOpenOcdScriptValue}",
"-ip",
"localhost",
"-dn",
"${config:idf.adapterTargetName}",
"-om",
"connect_to_instance"
],
"windows": {
"command": "${config:idf.pythonBinPathWin}",
"options": {
"env": {
"PATH": "${env:PATH};${config:idf.customExtraPaths}",
"PYTHONPATH": "${command:espIdf.getExtensionPath}/esp_debug_adapter/debug_adapter"
}
}
}
}
]
}

10
CMakeLists.txt Normal file
View File

@ -0,0 +1,10 @@
# For more information about build system see
# https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html
# The following five lines of boilerplate have to be in your project's
# CMakeLists in this exact order for cmake to work correctly
cmake_minimum_required(VERSION 3.5)
set(EXTRA_COMPONENT_DIRS $ENV{IDF_PATH}/examples/common_components/led_strip)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(screen-bg-light)

32
README.md Normal file
View File

@ -0,0 +1,32 @@
# _Sample project_
(See the README.md file in the upper level 'examples' directory for more information about examples.)
This is the simplest buildable example. The example is used by command `idf.py create-project`
that copies the project to user specified path and set it's name. For more information follow the [docs page](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html#start-a-new-project)
## How to use example
We encourage the users to use the example as a template for the new projects.
A recommended way is to follow the instructions on a [docs page](https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html#start-a-new-project).
## Example folder contents
The project **sample_project** contains one source file in C language [main.c](main/main.c). The file is located in folder [main](main).
ESP-IDF projects are built using CMake. The project build configuration is contained in `CMakeLists.txt`
files that provide set of directives and instructions describing the project's source files and targets
(executable, library, or both).
Below is short explanation of remaining files in the project folder.
```
├── CMakeLists.txt
├── main
│   ├── CMakeLists.txt
│   └── main.c
└── README.md This is the file you are currently reading
```
Additionally, the sample project contains Makefile and component.mk files, used for the legacy Make based build system.
They are not used or needed when building with CMake and idf.py.

2
main/CMakeLists.txt Normal file
View File

@ -0,0 +1,2 @@
idf_component_register(SRCS "main.c"
INCLUDE_DIRS ".")

120
main/main.c Normal file
View File

@ -0,0 +1,120 @@
/* RMT example -- RGB LED Strip
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
*/
#include "driver/rmt.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "led_strip.h"
#include "sdkconfig.h"
static const char *TAG = "example";
#define RMT_TX_CHANNEL RMT_CHANNEL_0
#define RMT_TX_GPIO 1
#define STRIP_LED_NUMBER 1
#define EXAMPLE_CHASE_SPEED_MS (10)
/**
* @brief Simple helper function, converting HSV color space to RGB color space
*
* Wiki: https://en.wikipedia.org/wiki/HSL_and_HSV
*
*/
void led_strip_hsv2rgb(uint32_t h, uint32_t s, uint32_t v, uint32_t *r,
uint32_t *g, uint32_t *b) {
h %= 360; // h -> [0,360]
uint32_t rgb_max = v * 2.55f;
uint32_t rgb_min = rgb_max * (100 - s) / 100.0f;
uint32_t i = h / 60;
uint32_t diff = h % 60;
// RGB adjustment amount by hue
uint32_t rgb_adj = (rgb_max - rgb_min) * diff / 60;
switch (i) {
case 0:
*r = rgb_max;
*g = rgb_min + rgb_adj;
*b = rgb_min;
break;
case 1:
*r = rgb_max - rgb_adj;
*g = rgb_max;
*b = rgb_min;
break;
case 2:
*r = rgb_min;
*g = rgb_max;
*b = rgb_min + rgb_adj;
break;
case 3:
*r = rgb_min;
*g = rgb_max - rgb_adj;
*b = rgb_max;
break;
case 4:
*r = rgb_min + rgb_adj;
*g = rgb_min;
*b = rgb_max;
break;
default:
*r = rgb_max;
*g = rgb_min;
*b = rgb_max - rgb_adj;
break;
}
}
void app_main(void) {
uint32_t red = 0;
uint32_t green = 0;
uint32_t blue = 0;
uint16_t hue = 0;
uint16_t start_rgb = 0;
rmt_config_t config = RMT_DEFAULT_CONFIG_TX(RMT_TX_GPIO, RMT_TX_CHANNEL);
// set counter clock to 40MHz
config.clk_div = 2;
ESP_ERROR_CHECK(rmt_config(&config));
ESP_ERROR_CHECK(rmt_driver_install(config.channel, 0, 0));
// install ws2812 driver
led_strip_config_t strip_config = LED_STRIP_DEFAULT_CONFIG(
STRIP_LED_NUMBER, (led_strip_dev_t)config.channel);
led_strip_t *strip = led_strip_new_rmt_ws2812(&strip_config);
if (!strip) {
ESP_LOGE(TAG, "install WS2812 driver failed");
}
// Clear LED strip (turn off all LEDs)
ESP_ERROR_CHECK(strip->clear(strip, 100));
// Show simple rainbow chasing pattern
ESP_LOGI(TAG, "LED Rainbow Chase Start");
while (true) {
for (int i = 0; i < 3; i++) {
for (int j = i; j < STRIP_LED_NUMBER; j += 3) {
// Build RGB values
hue = j * 360 / STRIP_LED_NUMBER + start_rgb;
led_strip_hsv2rgb(hue, 100, 100, &red, &green, &blue);
// Write RGB values to strip driver
ESP_ERROR_CHECK(strip->set_pixel(strip, j, red, green, blue));
}
// Flush RGB values to LEDs
ESP_ERROR_CHECK(strip->refresh(strip, 100));
vTaskDelay(pdMS_TO_TICKS(EXAMPLE_CHASE_SPEED_MS));
strip->clear(strip, 50);
vTaskDelay(pdMS_TO_TICKS(EXAMPLE_CHASE_SPEED_MS));
}
start_rgb += 60;
}
connect_wifi()
}