blob: b176bbb0fd7a727448e0b0d2fabe9cf945f79945 [file] [log] [blame]
/*
*
* 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 <assert.h>
#include <stdio.h>
#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__ */