mirror of
https://github.com/hathach/tinyusb.git
synced 2025-04-16 05:42:56 +00:00
Merge pull request #445 from hathach/add-kaluga-bsp
added esp32s2 kaluga bsp
This commit is contained in:
commit
2b9466dbc0
7
.github/workflows/build.yml
vendored
7
.github/workflows/build.yml
vendored
@ -79,6 +79,11 @@ jobs:
|
|||||||
# Build ESP32S
|
# Build ESP32S
|
||||||
build-esp32s:
|
build-esp32s:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
example: ['board_test', 'cdc_msc_freertos', 'hid_composite_freertos']
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Setup Python
|
- name: Setup Python
|
||||||
uses: actions/setup-python@v1
|
uses: actions/setup-python@v1
|
||||||
@ -92,4 +97,4 @@ jobs:
|
|||||||
submodules: 'false'
|
submodules: 'false'
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: docker run --rm -v $PWD:/project -w /project espressif/idf:latest python3 tools/build_esp32s.py
|
run: docker run --rm -v $PWD:/project -w /project espressif/idf:latest python3 tools/build_esp32s.py ${{ matrix.example }}
|
||||||
|
@ -11,6 +11,7 @@ This code base already had supported for a handful of following boards (sorted a
|
|||||||
|
|
||||||
### Espressif ESP32-S2
|
### Espressif ESP32-S2
|
||||||
|
|
||||||
|
- [ESP32-S2-Kaluga-1](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-esp32-s2-kaluga-1-kit.html)
|
||||||
- [ESP32-S2-Saola-1](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-saola-1-v1.2.html)
|
- [ESP32-S2-Saola-1](https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-saola-1-v1.2.html)
|
||||||
|
|
||||||
### MicroChip SAMD
|
### MicroChip SAMD
|
||||||
|
@ -7,7 +7,7 @@ set(TOP "../../..")
|
|||||||
get_filename_component(TOP "${TOP}" REALPATH)
|
get_filename_component(TOP "${TOP}" REALPATH)
|
||||||
|
|
||||||
# Add example src and bsp directories
|
# Add example src and bsp directories
|
||||||
set(EXTRA_COMPONENT_DIRS "src" "${TOP}/hw/bsp/esp32s2_saola_1")
|
set(EXTRA_COMPONENT_DIRS "src" "${TOP}/hw/bsp/${BOARD}")
|
||||||
|
|
||||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
set(SUPPORTED_TARGETS esp32s2)
|
set(SUPPORTED_TARGETS esp32s2)
|
||||||
|
@ -7,7 +7,7 @@ set(TOP "../../..")
|
|||||||
get_filename_component(TOP "${TOP}" REALPATH)
|
get_filename_component(TOP "${TOP}" REALPATH)
|
||||||
|
|
||||||
# Add example src and bsp directories
|
# Add example src and bsp directories
|
||||||
set(EXTRA_COMPONENT_DIRS "src" "${TOP}/hw/bsp/esp32s2_saola_1")
|
set(EXTRA_COMPONENT_DIRS "src" "${TOP}/hw/bsp/${BOARD}")
|
||||||
|
|
||||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
set(SUPPORTED_TARGETS esp32s2)
|
set(SUPPORTED_TARGETS esp32s2)
|
||||||
|
@ -7,7 +7,7 @@ set(TOP "../../..")
|
|||||||
get_filename_component(TOP "${TOP}" REALPATH)
|
get_filename_component(TOP "${TOP}" REALPATH)
|
||||||
|
|
||||||
# Add example src and bsp directories
|
# Add example src and bsp directories
|
||||||
set(EXTRA_COMPONENT_DIRS "src" "${TOP}/hw/bsp/esp32s2_saola_1")
|
set(EXTRA_COMPONENT_DIRS "src" "${TOP}/hw/bsp/${BOARD}")
|
||||||
|
|
||||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||||
set(SUPPORTED_TARGETS esp32s2)
|
set(SUPPORTED_TARGETS esp32s2)
|
||||||
|
@ -12,11 +12,10 @@ all:
|
|||||||
idf.py -B$(BUILD) -DBOARD=$(BOARD) build
|
idf.py -B$(BUILD) -DBOARD=$(BOARD) build
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
idf.py -B$(BUILD) clean
|
idf.py -B$(BUILD) -DBOARD=$(BOARD) clean
|
||||||
|
|
||||||
flash:
|
flash:
|
||||||
@:$(call check_defined, SERIAL, example: SERIAL=/dev/ttyUSB0)
|
idf.py -B$(BUILD) -DBOARD=$(BOARD) flash
|
||||||
idf.py -B$(BUILD) -p $(SERIAL) flash
|
|
||||||
|
|
||||||
else
|
else
|
||||||
# GNU Make build system
|
# GNU Make build system
|
||||||
|
16
hw/bsp/esp32s2_kaluga_1/CMakeLists.txt
Normal file
16
hw/bsp/esp32s2_kaluga_1/CMakeLists.txt
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
idf_component_register(SRCS "${BOARD}.c" "led_strip/src/led_strip_rmt_ws2812.c"
|
||||||
|
INCLUDE_DIRS "led_strip/include"
|
||||||
|
PRIV_REQUIRES "driver"
|
||||||
|
REQUIRES freertos src)
|
||||||
|
|
||||||
|
target_compile_options(${COMPONENT_TARGET} PUBLIC
|
||||||
|
"-DCFG_TUSB_MCU=OPT_MCU_ESP32S2"
|
||||||
|
"-DCFG_TUSB_OS=OPT_OS_FREERTOS"
|
||||||
|
)
|
||||||
|
|
||||||
|
idf_component_get_property( FREERTOS_ORIG_INCLUDE_PATH freertos ORIG_INCLUDE_PATH)
|
||||||
|
target_include_directories(${COMPONENT_TARGET} PUBLIC
|
||||||
|
"${FREERTOS_ORIG_INCLUDE_PATH}"
|
||||||
|
"${TOP}/hw"
|
||||||
|
"${TOP}/src"
|
||||||
|
)
|
2
hw/bsp/esp32s2_kaluga_1/board.mk
Normal file
2
hw/bsp/esp32s2_kaluga_1/board.mk
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# Cross Compiler for ESP32
|
||||||
|
CROSS_COMPILE = xtensa-esp32s2-elf-
|
108
hw/bsp/esp32s2_kaluga_1/esp32s2_kaluga_1.c
Normal file
108
hw/bsp/esp32s2_kaluga_1/esp32s2_kaluga_1.c
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
/*
|
||||||
|
* The MIT License (MIT)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2020, Ha Thach (tinyusb.org)
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* This file is part of the TinyUSB stack.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../board.h"
|
||||||
|
#include "driver/gpio.h"
|
||||||
|
#include "driver/periph_ctrl.h"
|
||||||
|
#include "hal/usb_hal.h"
|
||||||
|
#include "soc/usb_periph.h"
|
||||||
|
|
||||||
|
#include "driver/rmt.h"
|
||||||
|
#include "led_strip/include/led_strip.h"
|
||||||
|
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
// MACRO TYPEDEF CONSTANT ENUM DECLARATION
|
||||||
|
//--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
#define LED_PIN 45
|
||||||
|
|
||||||
|
#define BUTTON_PIN 0
|
||||||
|
#define BUTTON_STATE_ACTIVE 0
|
||||||
|
|
||||||
|
|
||||||
|
static led_strip_t *strip;
|
||||||
|
|
||||||
|
// Initialize on-board peripherals : led, button, uart and USB
|
||||||
|
void board_init(void)
|
||||||
|
{
|
||||||
|
// WS2812 Neopixel driver with RMT peripheral
|
||||||
|
rmt_config_t config = RMT_DEFAULT_CONFIG_TX(LED_PIN, RMT_CHANNEL_0);
|
||||||
|
config.clk_div = 2; // set counter clock to 40MHz
|
||||||
|
|
||||||
|
rmt_config(&config);
|
||||||
|
rmt_driver_install(config.channel, 0, 0);
|
||||||
|
|
||||||
|
led_strip_config_t strip_config = LED_STRIP_DEFAULT_CONFIG(1, (led_strip_dev_t) config.channel);
|
||||||
|
strip = led_strip_new_rmt_ws2812(&strip_config);
|
||||||
|
strip->clear(strip, 100); // off led
|
||||||
|
|
||||||
|
// Button
|
||||||
|
gpio_pad_select_gpio(BUTTON_PIN);
|
||||||
|
gpio_set_direction(BUTTON_PIN, GPIO_MODE_INPUT);
|
||||||
|
gpio_set_pull_mode(BUTTON_PIN, BUTTON_STATE_ACTIVE ? GPIO_PULLDOWN_ONLY : GPIO_PULLUP_ONLY);
|
||||||
|
|
||||||
|
// USB Controller Hal init
|
||||||
|
periph_module_reset(PERIPH_USB_MODULE);
|
||||||
|
periph_module_enable(PERIPH_USB_MODULE);
|
||||||
|
|
||||||
|
usb_hal_context_t hal = {
|
||||||
|
.use_external_phy = false // use built-in PHY
|
||||||
|
};
|
||||||
|
usb_hal_init(&hal);
|
||||||
|
|
||||||
|
// Pin drive strength
|
||||||
|
gpio_set_drive_capability(USBPHY_DM_NUM, GPIO_DRIVE_CAP_3);
|
||||||
|
gpio_set_drive_capability(USBPHY_DP_NUM, GPIO_DRIVE_CAP_3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Turn LED on or off
|
||||||
|
void board_led_write(bool state)
|
||||||
|
{
|
||||||
|
strip->set_pixel(strip, 0, (state ? 0x88 : 0x00), 0x00, 0x00);
|
||||||
|
strip->refresh(strip, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the current state of button
|
||||||
|
// a '1' means active (pressed), a '0' means inactive.
|
||||||
|
uint32_t board_button_read(void)
|
||||||
|
{
|
||||||
|
return gpio_get_level(BUTTON_PIN) == BUTTON_STATE_ACTIVE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get characters from UART
|
||||||
|
int board_uart_read(uint8_t* buf, int len)
|
||||||
|
{
|
||||||
|
(void) buf; (void) len;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send characters to UART
|
||||||
|
int board_uart_write(void const * buf, int len)
|
||||||
|
{
|
||||||
|
(void) buf; (void) len;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
126
hw/bsp/esp32s2_kaluga_1/led_strip/include/led_strip.h
Normal file
126
hw/bsp/esp32s2_kaluga_1/led_strip/include/led_strip.h
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
// Copyright 2019 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.
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "esp_err.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief LED Strip Type
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct led_strip_s led_strip_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief LED Strip Device Type
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef void *led_strip_dev_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Declare of LED Strip Type
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
struct led_strip_s {
|
||||||
|
/**
|
||||||
|
* @brief Set RGB for a specific pixel
|
||||||
|
*
|
||||||
|
* @param strip: LED strip
|
||||||
|
* @param index: index of pixel to set
|
||||||
|
* @param red: red part of color
|
||||||
|
* @param green: green part of color
|
||||||
|
* @param blue: blue part of color
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK: Set RGB for a specific pixel successfully
|
||||||
|
* - ESP_ERR_INVALID_ARG: Set RGB for a specific pixel failed because of invalid parameters
|
||||||
|
* - ESP_FAIL: Set RGB for a specific pixel failed because other error occurred
|
||||||
|
*/
|
||||||
|
esp_err_t (*set_pixel)(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Refresh memory colors to LEDs
|
||||||
|
*
|
||||||
|
* @param strip: LED strip
|
||||||
|
* @param timeout_ms: timeout value for refreshing task
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK: Refresh successfully
|
||||||
|
* - ESP_ERR_TIMEOUT: Refresh failed because of timeout
|
||||||
|
* - ESP_FAIL: Refresh failed because some other error occurred
|
||||||
|
*
|
||||||
|
* @note:
|
||||||
|
* After updating the LED colors in the memory, a following invocation of this API is needed to flush colors to strip.
|
||||||
|
*/
|
||||||
|
esp_err_t (*refresh)(led_strip_t *strip, uint32_t timeout_ms);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Clear LED strip (turn off all LEDs)
|
||||||
|
*
|
||||||
|
* @param strip: LED strip
|
||||||
|
* @param timeout_ms: timeout value for clearing task
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK: Clear LEDs successfully
|
||||||
|
* - ESP_ERR_TIMEOUT: Clear LEDs failed because of timeout
|
||||||
|
* - ESP_FAIL: Clear LEDs failed because some other error occurred
|
||||||
|
*/
|
||||||
|
esp_err_t (*clear)(led_strip_t *strip, uint32_t timeout_ms);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Free LED strip resources
|
||||||
|
*
|
||||||
|
* @param strip: LED strip
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* - ESP_OK: Free resources successfully
|
||||||
|
* - ESP_FAIL: Free resources failed because error occurred
|
||||||
|
*/
|
||||||
|
esp_err_t (*del)(led_strip_t *strip);
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief LED Strip Configuration Type
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
uint32_t max_leds; /*!< Maximum LEDs in a single strip */
|
||||||
|
led_strip_dev_t dev; /*!< LED strip device (e.g. RMT channel, PWM channel, etc) */
|
||||||
|
} led_strip_config_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Default configuration for LED strip
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#define LED_STRIP_DEFAULT_CONFIG(number, dev_hdl) \
|
||||||
|
{ \
|
||||||
|
.max_leds = number, \
|
||||||
|
.dev = dev_hdl, \
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Install a new ws2812 driver (based on RMT peripheral)
|
||||||
|
*
|
||||||
|
* @param config: LED strip configuration
|
||||||
|
* @return
|
||||||
|
* LED strip instance or NULL
|
||||||
|
*/
|
||||||
|
led_strip_t *led_strip_new_rmt_ws2812(const led_strip_config_t *config);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
171
hw/bsp/esp32s2_kaluga_1/led_strip/src/led_strip_rmt_ws2812.c
Normal file
171
hw/bsp/esp32s2_kaluga_1/led_strip/src/led_strip_rmt_ws2812.c
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
// Copyright 2019 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 <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
#include "esp_log.h"
|
||||||
|
#include "esp_attr.h"
|
||||||
|
#include "led_strip.h"
|
||||||
|
#include "driver/rmt.h"
|
||||||
|
|
||||||
|
static const char *TAG = "ws2812";
|
||||||
|
#define STRIP_CHECK(a, str, goto_tag, ret_value, ...) \
|
||||||
|
do \
|
||||||
|
{ \
|
||||||
|
if (!(a)) \
|
||||||
|
{ \
|
||||||
|
ESP_LOGE(TAG, "%s(%d): " str, __FUNCTION__, __LINE__, ##__VA_ARGS__); \
|
||||||
|
ret = ret_value; \
|
||||||
|
goto goto_tag; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define WS2812_T0H_NS (350)
|
||||||
|
#define WS2812_T0L_NS (1000)
|
||||||
|
#define WS2812_T1H_NS (1000)
|
||||||
|
#define WS2812_T1L_NS (350)
|
||||||
|
#define WS2812_RESET_US (280)
|
||||||
|
|
||||||
|
static uint32_t ws2812_t0h_ticks = 0;
|
||||||
|
static uint32_t ws2812_t1h_ticks = 0;
|
||||||
|
static uint32_t ws2812_t0l_ticks = 0;
|
||||||
|
static uint32_t ws2812_t1l_ticks = 0;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
led_strip_t parent;
|
||||||
|
rmt_channel_t rmt_channel;
|
||||||
|
uint32_t strip_len;
|
||||||
|
uint8_t buffer[0];
|
||||||
|
} ws2812_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Conver RGB data to RMT format.
|
||||||
|
*
|
||||||
|
* @note For WS2812, R,G,B each contains 256 different choices (i.e. uint8_t)
|
||||||
|
*
|
||||||
|
* @param[in] src: source data, to converted to RMT format
|
||||||
|
* @param[in] dest: place where to store the convert result
|
||||||
|
* @param[in] src_size: size of source data
|
||||||
|
* @param[in] wanted_num: number of RMT items that want to get
|
||||||
|
* @param[out] translated_size: number of source data that got converted
|
||||||
|
* @param[out] item_num: number of RMT items which are converted from source data
|
||||||
|
*/
|
||||||
|
static void IRAM_ATTR ws2812_rmt_adapter(const void *src, rmt_item32_t *dest, size_t src_size,
|
||||||
|
size_t wanted_num, size_t *translated_size, size_t *item_num)
|
||||||
|
{
|
||||||
|
if (src == NULL || dest == NULL) {
|
||||||
|
*translated_size = 0;
|
||||||
|
*item_num = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const rmt_item32_t bit0 = {{{ ws2812_t0h_ticks, 1, ws2812_t0l_ticks, 0 }}}; //Logical 0
|
||||||
|
const rmt_item32_t bit1 = {{{ ws2812_t1h_ticks, 1, ws2812_t1l_ticks, 0 }}}; //Logical 1
|
||||||
|
size_t size = 0;
|
||||||
|
size_t num = 0;
|
||||||
|
uint8_t *psrc = (uint8_t *)src;
|
||||||
|
rmt_item32_t *pdest = dest;
|
||||||
|
while (size < src_size && num < wanted_num) {
|
||||||
|
for (int i = 0; i < 8; i++) {
|
||||||
|
// MSB first
|
||||||
|
if (*psrc & (1 << (7 - i))) {
|
||||||
|
pdest->val = bit1.val;
|
||||||
|
} else {
|
||||||
|
pdest->val = bit0.val;
|
||||||
|
}
|
||||||
|
num++;
|
||||||
|
pdest++;
|
||||||
|
}
|
||||||
|
size++;
|
||||||
|
psrc++;
|
||||||
|
}
|
||||||
|
*translated_size = size;
|
||||||
|
*item_num = num;
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t ws2812_set_pixel(led_strip_t *strip, uint32_t index, uint32_t red, uint32_t green, uint32_t blue)
|
||||||
|
{
|
||||||
|
esp_err_t ret = ESP_OK;
|
||||||
|
ws2812_t *ws2812 = __containerof(strip, ws2812_t, parent);
|
||||||
|
STRIP_CHECK(index < ws2812->strip_len, "index out of the maximum number of leds", err, ESP_ERR_INVALID_ARG);
|
||||||
|
uint32_t start = index * 3;
|
||||||
|
// In thr order of GRB
|
||||||
|
ws2812->buffer[start + 0] = green & 0xFF;
|
||||||
|
ws2812->buffer[start + 1] = red & 0xFF;
|
||||||
|
ws2812->buffer[start + 2] = blue & 0xFF;
|
||||||
|
return ESP_OK;
|
||||||
|
err:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t ws2812_refresh(led_strip_t *strip, uint32_t timeout_ms)
|
||||||
|
{
|
||||||
|
esp_err_t ret = ESP_OK;
|
||||||
|
ws2812_t *ws2812 = __containerof(strip, ws2812_t, parent);
|
||||||
|
STRIP_CHECK(rmt_write_sample(ws2812->rmt_channel, ws2812->buffer, ws2812->strip_len * 3, true) == ESP_OK,
|
||||||
|
"transmit RMT samples failed", err, ESP_FAIL);
|
||||||
|
return rmt_wait_tx_done(ws2812->rmt_channel, pdMS_TO_TICKS(timeout_ms));
|
||||||
|
err:
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t ws2812_clear(led_strip_t *strip, uint32_t timeout_ms)
|
||||||
|
{
|
||||||
|
ws2812_t *ws2812 = __containerof(strip, ws2812_t, parent);
|
||||||
|
// Write zero to turn off all leds
|
||||||
|
memset(ws2812->buffer, 0, ws2812->strip_len * 3);
|
||||||
|
return ws2812_refresh(strip, timeout_ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
static esp_err_t ws2812_del(led_strip_t *strip)
|
||||||
|
{
|
||||||
|
ws2812_t *ws2812 = __containerof(strip, ws2812_t, parent);
|
||||||
|
free(ws2812);
|
||||||
|
return ESP_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
led_strip_t *led_strip_new_rmt_ws2812(const led_strip_config_t *config)
|
||||||
|
{
|
||||||
|
led_strip_t *ret = NULL;
|
||||||
|
STRIP_CHECK(config, "configuration can't be null", err, NULL);
|
||||||
|
|
||||||
|
// 24 bits per led
|
||||||
|
uint32_t ws2812_size = sizeof(ws2812_t) + config->max_leds * 3;
|
||||||
|
ws2812_t *ws2812 = calloc(1, ws2812_size);
|
||||||
|
STRIP_CHECK(ws2812, "request memory for ws2812 failed", err, NULL);
|
||||||
|
|
||||||
|
uint32_t counter_clk_hz = 0;
|
||||||
|
STRIP_CHECK(rmt_get_counter_clock((rmt_channel_t)config->dev, &counter_clk_hz) == ESP_OK,
|
||||||
|
"get rmt counter clock failed", err, NULL);
|
||||||
|
// ns -> ticks
|
||||||
|
float ratio = (float)counter_clk_hz / 1e9;
|
||||||
|
ws2812_t0h_ticks = (uint32_t)(ratio * WS2812_T0H_NS);
|
||||||
|
ws2812_t0l_ticks = (uint32_t)(ratio * WS2812_T0L_NS);
|
||||||
|
ws2812_t1h_ticks = (uint32_t)(ratio * WS2812_T1H_NS);
|
||||||
|
ws2812_t1l_ticks = (uint32_t)(ratio * WS2812_T1L_NS);
|
||||||
|
|
||||||
|
// set ws2812 to rmt adapter
|
||||||
|
rmt_translator_init((rmt_channel_t)config->dev, ws2812_rmt_adapter);
|
||||||
|
|
||||||
|
ws2812->rmt_channel = (rmt_channel_t)config->dev;
|
||||||
|
ws2812->strip_len = config->max_leds;
|
||||||
|
|
||||||
|
ws2812->parent.set_pixel = ws2812_set_pixel;
|
||||||
|
ws2812->parent.refresh = ws2812_refresh;
|
||||||
|
ws2812->parent.clear = ws2812_clear;
|
||||||
|
ws2812->parent.del = ws2812_del;
|
||||||
|
|
||||||
|
return &ws2812->parent;
|
||||||
|
err:
|
||||||
|
return ret;
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
idf_component_register(SRCS "esp32s2_saola_1.c" "led_strip/src/led_strip_rmt_ws2812.c"
|
idf_component_register(SRCS "${BOARD}.c" "led_strip/src/led_strip_rmt_ws2812.c"
|
||||||
INCLUDE_DIRS "led_strip/include"
|
INCLUDE_DIRS "led_strip/include"
|
||||||
PRIV_REQUIRES "driver"
|
PRIV_REQUIRES "driver"
|
||||||
REQUIRES freertos src)
|
REQUIRES freertos src)
|
||||||
|
@ -39,8 +39,8 @@
|
|||||||
|
|
||||||
// Note: On the production version (v1.2) WS2812 is connected to GPIO 18,
|
// Note: On the production version (v1.2) WS2812 is connected to GPIO 18,
|
||||||
// however earlier revision v1.1 WS2812 is connected to GPIO 17
|
// however earlier revision v1.1 WS2812 is connected to GPIO 17
|
||||||
//#define LED_PIN 18 // v1.2 and later
|
//#define LED_PIN 17 // v1.1
|
||||||
#define LED_PIN 17 // v1.1
|
#define LED_PIN 18 // v1.2 and later
|
||||||
|
|
||||||
#define BUTTON_PIN 0
|
#define BUTTON_PIN 0
|
||||||
#define BUTTON_STATE_ACTIVE 0
|
#define BUTTON_STATE_ACTIVE 0
|
||||||
|
Loading…
x
Reference in New Issue
Block a user