/* * * Copyright (c) 2021 Project CHIP Authors * * 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. */ #ifdef __PWM_DIMMABLE_LED__ #include "DimmableLEDWidget.h" #include #include #include "hal_pwm.h" #define LIGHT_LEVEL_MIN (0) #define LIGHT_LEVEL_MAX (100) #define LIGHT_LEVEL_DEFAULT (50) #define PWM_FREQUENCY_DEFAULT (1000) #define LEVEL_TO_PWM_RATIO(level) ((level) *10) static hal_pwm_channel_t convert_gpio_to_pwm_channel(hal_gpio_pin_t gpio) { hal_pwm_channel_t ret = HAL_PWM_MAX; if (gpio >= HAL_GPIO_29 && gpio <= HAL_GPIO_40) { ret = (hal_pwm_channel_t) (gpio - HAL_GPIO_29); } else if (gpio >= HAL_GPIO_45 && gpio <= HAL_GPIO_52) { ret = (hal_pwm_channel_t) (gpio - HAL_GPIO_45); } else { assert(false); } return ret; } void DimmableLEDWidget::Init(hal_gpio_pin_t gpio) { hal_pwm_channel_t pwm_channel = HAL_PWM_MAX; uint32_t total_count = 0; mGpioPin = gpio; mState = false; mLevel = LIGHT_LEVEL_DEFAULT; hal_gpio_init(mGpioPin); if (mGpioPin >= HAL_GPIO_29 && mGpioPin <= HAL_GPIO_40) { assert(HAL_PINMUX_STATUS_OK == hal_pinmux_set_function(mGpioPin, 3)); } else if (mGpioPin >= HAL_GPIO_45 && mGpioPin <= HAL_GPIO_52) { assert(HAL_PINMUX_STATUS_OK == hal_pinmux_set_function(mGpioPin, 5)); } else { /* This GPIO is not supported PWM */ assert(false); } pwm_channel = convert_gpio_to_pwm_channel(mGpioPin); assert(HAL_PWM_STATUS_OK == hal_pwm_init(pwm_channel, HAL_PWM_CLOCK_26MHZ)); assert(HAL_PWM_STATUS_OK == hal_pwm_set_frequency(pwm_channel, PWM_FREQUENCY_DEFAULT, &total_count)); assert(HAL_PWM_STATUS_OK == hal_pwm_set_duty_cycle(pwm_channel, LEVEL_TO_PWM_RATIO(mLevel))); } void DimmableLEDWidget::Set(bool state) { hal_pwm_channel_t pwm_channel = convert_gpio_to_pwm_channel(mGpioPin); if (state && !mState) { mState = true; assert(HAL_PWM_STATUS_OK == hal_pwm_start(pwm_channel)); } else if (!state && mState) { mState = false; assert(HAL_PWM_STATUS_OK == hal_pwm_stop(pwm_channel)); } } bool DimmableLEDWidget::Get(void) { return mState; } void DimmableLEDWidget::SetLevel(uint8_t level) { hal_pwm_channel_t pwm_channel = convert_gpio_to_pwm_channel(mGpioPin); if (level >= LIGHT_LEVEL_MIN && level <= LIGHT_LEVEL_MAX && level != mLevel) { mLevel = level; assert(HAL_PWM_STATUS_OK == hal_pwm_set_duty_cycle(pwm_channel, LEVEL_TO_PWM_RATIO(mLevel))); } } uint8_t DimmableLEDWidget::GetLevel(void) { return mLevel; } uint8_t DimmableLEDWidget::GetMaxLevel(void) { return LIGHT_LEVEL_MAX; } uint8_t DimmableLEDWidget::GetMinLevel(void) { return LIGHT_LEVEL_MIN; } #endif /* __PWM_DIMMABLE_LED__ */