Skip to content

Commit

Permalink
ESP32C3 Support: (project-chip#8201)
Browse files Browse the repository at this point in the history
use onboard RGB-LED(WS2812) for status-LED in all-clusters-app
add colorcontrol cluster for ESP32C3_DevkitM
  • Loading branch information
wqx6 authored Jul 9, 2021
1 parent 0b78067 commit a999ccd
Show file tree
Hide file tree
Showing 9 changed files with 181 additions and 20 deletions.
11 changes: 5 additions & 6 deletions examples/all-clusters-app/esp32/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,11 @@ set(EXTRA_COMPONENT_DIRS
"${CMAKE_CURRENT_LIST_DIR}/../../common/QRCode"
)
if(${IDF_TARGET} STREQUAL "esp32")
set(EXTRA_COMPONENT_DIRS
${EXTRA_COMPONENT_DIRS}
"${CMAKE_CURRENT_LIST_DIR}/../../common/m5stack-tft/repo/components/tft"
"${CMAKE_CURRENT_LIST_DIR}/../../common/m5stack-tft/repo/components/spidriver"
"${CMAKE_CURRENT_LIST_DIR}/../../common/screen-framework"
)
list(APPEND EXTRA_COMPONENT_DIRS "${CMAKE_CURRENT_LIST_DIR}/../../common/m5stack-tft/repo/components/tft"
"${CMAKE_CURRENT_LIST_DIR}/../../common/m5stack-tft/repo/components/spidriver"
"${CMAKE_CURRENT_LIST_DIR}/../../common/screen-framework")
elseif(${IDF_TARGET} STREQUAL "esp32c3")
list(APPEND EXTRA_COMPONENT_DIRS "$ENV{IDF_PATH}/examples/peripherals/rmt/led_strip/components")
endif()

project(chip-all-clusters-app)
Expand Down
25 changes: 19 additions & 6 deletions examples/all-clusters-app/esp32/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,11 +209,23 @@ commissioning and cluster control.

### Cluster control

- After successful commissioning, use the OnOff cluster command to control the
OnOff attribute. This allows you to toggle a parameter implemented by the
device to be On or Off.
- After successful commissioning, use the OnOff cluster commands to control
the OnOff attribute. This allows you to toggle a parameter implemented by
the device to be On or Off.

`chip-device-ctrl > zcl OnOff Off 135246 1 0`
`chip-device-ctrl > zcl OnOff Off 135246 1 1`

- Use the LevelControl cluster commands to control the CurrentLevel attribute.
This allows you to control the brightness of the led.

`chip-device-ctrl > zcl LevelControl MoveToLevel 135246 1 1 level=10 transitionTime=0 optionMask=0 optionOverride=0`

- For ESP32C3-DevKitM, use the ColorContorl cluster commands to control the
CurrentHue and CurrentSaturation attribute. This allows you to control the
color of on-board LED.

`zcl ColorControl MoveToHue 135246 1 1 hue=100 direction=0 transitionTime=0 optionsMask=0 optionsOverride=0`
`zcl ColorControl MoveToSaturation 135245 1 1 saturation=200 transitionTime=0 optionsMask=0 optionsOverride=0`

### Flashing app using script

Expand Down Expand Up @@ -243,5 +255,6 @@ through the on/off/toggle commands from the `python-controller`. For `M5Stack`,
a virtual Green LED on the display is used for the same.

If you wish to see the actual effect of the commands on `ESP32-DevKitC`,
`ESP32-WROVER-KIT_V4.1` and `ESP32C3-DevKitM`, you will have to connect an
external LED to GPIO `STATUS_LED_GPIO_NUM`.
`ESP32-WROVER-KIT_V4.1`, you will have to connect an external LED to GPIO
`STATUS_LED_GPIO_NUM`. For `ESP32C3-DevKitM`, the on-board LED will show the
actual effect of the commands.
8 changes: 6 additions & 2 deletions examples/all-clusters-app/esp32/main/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,17 @@ set(SRC_DIRS_LIST
)

if(("${CONFIG_DEVICE_TYPE_ESP32_DEVKITC}" STREQUAL "y") OR ("${CONFIG_DEVICE_TYPE_ESP32_C3_DEVKITM}" STREQUAL "y"))
set(PRIV_INCLUDE_DIRS_LIST ${PRIV_INCLUDE_DIRS_LIST}
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/common/screen-framework/include")
list(APPEND PRIV_INCLUDE_DIRS_LIST
"${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/examples/common/screen-framework/include")
set(PRIV_REQUIRES_LIST chip QRCode bt)
elseif(("${CONFIG_DEVICE_TYPE_M5STACK}" STREQUAL "y") OR ("${CONFIG_DEVICE_TYPE_ESP32_WROVER_KIT}" STREQUAL "y"))
set(PRIV_REQUIRES_LIST chip QRCode bt tft spidrier screen-framework)
endif()

if("${CONFIG_DEVICE_TYPE_ESP32_C3_DEVKITM}" STREQUAL "y")
list(APPEND PRIV_REQUIRES_LIST led_strip)
endif()

idf_component_register(PRIV_INCLUDE_DIRS ${PRIV_INCLUDE_DIRS_LIST}
SRC_DIRS ${SRC_DIRS_LIST}
PRIV_REQUIRES ${PRIV_REQUIRES_LIST})
Expand Down
36 changes: 35 additions & 1 deletion examples/all-clusters-app/esp32/main/DeviceCallbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,11 @@ void DeviceCallbacks::PostAttributeChangeCallback(EndpointId endpointId, Cluster
case ZCL_LEVEL_CONTROL_CLUSTER_ID:
OnLevelControlAttributeChangeCallback(endpointId, attributeId, value);
break;

#if CONFIG_DEVICE_TYPE_ESP32_C3_DEVKITM
case ZCL_COLOR_CONTROL_CLUSTER_ID:
OnColorControlAttributeChangeCallback(endpointId, attributeId, value);
break;
#endif
default:
ESP_LOGI(TAG, "Unhandled cluster ID: %d", clusterId);
break;
Expand Down Expand Up @@ -164,6 +168,36 @@ void DeviceCallbacks::OnLevelControlAttributeChangeCallback(EndpointId endpointI
return;
}

// Currently we only support ColorControl cluster for ESP32C3_DEVKITM which has an on-board RGB-LED
#if CONFIG_DEVICE_TYPE_ESP32_C3_DEVKITM
void DeviceCallbacks::OnColorControlAttributeChangeCallback(EndpointId endpointId, AttributeId attributeId, uint8_t * value)
{
VerifyOrExit(attributeId == ZCL_COLOR_CONTROL_CURRENT_HUE_ATTRIBUTE_ID ||
attributeId == ZCL_COLOR_CONTROL_CURRENT_SATURATION_ATTRIBUTE_ID,
ESP_LOGI(TAG, "Unhandled AttributeId ID: '0x%04x", attributeId));
VerifyOrExit(endpointId == 1 || endpointId == 2, ESP_LOGE(TAG, "Unexpected EndPoint ID: `0x%02x'", endpointId));
if (endpointId == 1)
{
uint8_t hue, saturation;
if (attributeId == ZCL_COLOR_CONTROL_CURRENT_HUE_ATTRIBUTE_ID)
{
hue = *value;
emberAfReadServerAttribute(endpointId, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_CURRENT_SATURATION_ATTRIBUTE_ID,
&saturation, sizeof(uint8_t));
}
else
{
saturation = *value;
emberAfReadServerAttribute(endpointId, ZCL_COLOR_CONTROL_CLUSTER_ID, ZCL_COLOR_CONTROL_CURRENT_HUE_ATTRIBUTE_ID, &hue,
sizeof(uint8_t));
}
statusLED1.SetColor(hue, saturation);
}
exit:
return;
}
#endif

void IdentifyTimerHandler(Layer * systemLayer, void * appState, CHIP_ERROR error)
{
statusLED1.Animate();
Expand Down
3 changes: 2 additions & 1 deletion examples/all-clusters-app/esp32/main/Kconfig.projbuild
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ menu "Demo"

choice
prompt "Device Type"
default DEVICE_TYPE_ESP32_DEVKITC
default DEVICE_TYPE_ESP32_DEVKITC if IDF_TARGET_ESP32
default DEVICE_TYPE_ESP32_C3_DEVKITM if IDF_TARGET_ESP32C3
help
Specifies the type of ESP32 device.

Expand Down
105 changes: 102 additions & 3 deletions examples/all-clusters-app/esp32/main/LEDWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,12 +27,19 @@

#include "ScreenManager.h"

#include "driver/ledc.h"
#include "esp_log.h"
#include "esp_system.h"
#include "esp_timer.h"
#if CONFIG_DEVICE_TYPE_ESP32_C3_DEVKITM
#include "driver/rmt.h"
#include "led_strip.h"
#define RMT_TX_DEFAULT_GPIO GPIO_NUM_8
#define RMT_TX_DEFAULT_CHANNEL RMT_CHANNEL_0
static led_strip_t * strip = NULL;
#else
#include "driver/ledc.h"
#include "hal/ledc_types.h"

#endif
void LEDWidget::Init(gpio_num_t gpioNum)
{
mLastChangeTimeUS = 0;
Expand All @@ -44,7 +51,20 @@ void LEDWidget::Init(gpio_num_t gpioNum)
mState = false;
mError = false;
errorTimer = NULL;

#if CONFIG_DEVICE_TYPE_ESP32_C3_DEVKITM
if (gpioNum == RMT_TX_DEFAULT_GPIO)
{
rmt_config_t config = RMT_DEFAULT_CONFIG_TX(RMT_TX_DEFAULT_GPIO, RMT_TX_DEFAULT_CHANNEL);
config.clk_div = 2;
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);
mDefaultOnBrightness = UINT8_MAX;
mHue = 0;
mSaturation = 0;
}
#else
if (gpioNum < GPIO_NUM_MAX)
{
ledc_timer_config_t ledc_timer = {
Expand All @@ -67,6 +87,7 @@ void LEDWidget::Init(gpio_num_t gpioNum)
ledc_channel_config(&ledc_channel);
mDefaultOnBrightness = UINT8_MAX;
}
#endif
}

void LEDWidget::Set(bool state)
Expand All @@ -77,11 +98,21 @@ void LEDWidget::Set(bool state)

void LEDWidget::SetBrightness(uint8_t brightness)
{
#if CONFIG_DEVICE_TYPE_ESP32_C3_DEVKITM
if (strip)
{
uint8_t red, green, blue;
HSB2rgb(mHue, mSaturation, brightness, red, green, blue);
strip->set_pixel(strip, 0, red, green, blue);
strip->refresh(strip, 100);
}
#else
if (mGPIONum < GPIO_NUM_MAX)
{
ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, brightness);
ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0);
}
#endif
if (brightness > 0)
{
mDefaultOnBrightness = brightness;
Expand Down Expand Up @@ -155,11 +186,22 @@ void LEDWidget::DoSet(bool state)
{
bool stateChange = (mState != state);
mState = state;
#if CONFIG_DEVICE_TYPE_ESP32_C3_DEVKITM
if (strip)
{
uint8_t red, green, blue;
uint8_t brightness = state ? mDefaultOnBrightness : 0;
HSB2rgb(mHue, mSaturation, brightness, red, green, blue);
strip->set_pixel(strip, 0, red, green, blue);
strip->refresh(strip, 100);
}
#else
if (mGPIONum < GPIO_NUM_MAX)
{
ledc_set_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0, state ? mDefaultOnBrightness : 0);
ledc_update_duty(LEDC_LOW_SPEED_MODE, LEDC_CHANNEL_0);
}
#endif
if (stateChange)
{
#if CONFIG_HAVE_DISPLAY
Expand All @@ -186,3 +228,60 @@ void LEDWidget::SetVLED(int id1, int id2)
}
}
#endif

#if CONFIG_DEVICE_TYPE_ESP32_C3_DEVKITM
void LEDWidget::SetColor(uint8_t Hue, uint8_t Saturation)
{
uint8_t red, green, blue;
uint8_t brightness = mState ? mDefaultOnBrightness : 0;
mHue = static_cast<uint16_t>(Hue) * 360 / 254; // mHue [0, 360]
mSaturation = static_cast<uint16_t>(Saturation) * 100 / 254; // mSaturation [0 , 100]

HSB2rgb(mHue, mSaturation, brightness, red, green, blue);
strip->set_pixel(strip, 0, red, green, blue);
strip->refresh(strip, 100);
}

void LEDWidget::HSB2rgb(uint16_t Hue, uint8_t Saturation, uint8_t brightness, uint8_t & red, uint8_t & green, uint8_t & blue)
{
uint16_t i = Hue / 60;
uint16_t rgb_max = brightness;
uint16_t rgb_min = rgb_max * (100 - Saturation) / 100;
uint16_t diff = Hue % 60;
uint16_t rgb_adj = (rgb_max - rgb_min) * diff / 60;

switch (i)
{
case 0:
red = rgb_max;
green = rgb_min + rgb_adj;
blue = rgb_min;
break;
case 1:
red = rgb_max - rgb_adj;
green = rgb_max;
blue = rgb_min;
break;
case 2:
red = rgb_min;
green = rgb_max;
blue = rgb_min + rgb_adj;
break;
case 3:
red = rgb_min;
green = rgb_max - rgb_adj;
blue = rgb_max;
break;
case 4:
red = rgb_min + rgb_adj;
green = rgb_min;
blue = rgb_max;
break;
default:
red = rgb_max;
green = rgb_min;
blue = rgb_max - rgb_adj;
break;
}
}
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ class DeviceCallbacks : public chip::DeviceManager::CHIPDeviceManagerCallbacks
void OnSessionEstablished(const chip::DeviceLayer::ChipDeviceEvent * event);
void OnOnOffPostAttributeChangeCallback(chip::EndpointId endpointId, chip::AttributeId attributeId, uint8_t * value);
void OnLevelControlAttributeChangeCallback(chip::EndpointId endpointId, chip::AttributeId attributeId, uint8_t * value);
#if CONFIG_DEVICE_TYPE_ESP32_C3_DEVKITM
void OnColorControlAttributeChangeCallback(chip::EndpointId endpointId, chip::AttributeId attributeId, uint8_t * value);
#endif
void OnIdentifyPostAttributeChangeCallback(chip::EndpointId endpointId, chip::AttributeId attributeId, uint8_t * value);

bool mEndpointOnOffState[2];
Expand Down
8 changes: 8 additions & 0 deletions examples/all-clusters-app/esp32/main/include/LEDWidget.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,11 @@ class LEDWidget
void BlinkOnError();

void Animate();
#if CONFIG_DEVICE_TYPE_ESP32_C3_DEVKITM
void SetColor(uint8_t Hue, uint8_t Saturation);

void HSB2rgb(uint16_t Hue, uint8_t Saturation, uint8_t brightness, uint8_t & red, uint8_t & green, uint8_t & blue);
#endif
#if CONFIG_HAVE_DISPLAY
void SetVLED(int id1, int id2);
#endif
Expand All @@ -55,6 +59,10 @@ class LEDWidget
uint32_t mBlinkOnTimeMS;
uint32_t mBlinkOffTimeMS;
uint8_t mDefaultOnBrightness;
#if CONFIG_DEVICE_TYPE_ESP32_C3_DEVKITM
uint16_t mHue; // mHue [0, 360]
uint8_t mSaturation; // mSaturation [0, 100]
#endif
gpio_num_t mGPIONum;
int mVLED1;
int mVLED2;
Expand Down
2 changes: 1 addition & 1 deletion examples/all-clusters-app/esp32/main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ using namespace ::chip::DeviceLayer;

#elif CONFIG_DEVICE_TYPE_ESP32_C3_DEVKITM

#define STATUS_LED_GPIO_NUM GPIO_NUM_2
#define STATUS_LED_GPIO_NUM GPIO_NUM_8

#else // !CONFIG_DEVICE_TYPE_ESP32_DEVKITC

Expand Down

0 comments on commit a999ccd

Please sign in to comment.