blob: 987b66518d44ca1ab9fb83a88db182e356848846 [file] [log] [blame]
/*
* Copyright (c) 2022 Project CHIP Authors
* All rights reserved.
*
* 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 "PWMManager.h"
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(PwmManager, CONFIG_CHIP_APP_LOG_LEVEL);
PwmManager & PwmManager::getInstance()
{
static PwmManager instance;
return instance;
}
PwmManager::PwmManager() : m_pwms{}, m_backend(NULL) {}
void PwmManager::setPwm(EAppPwm appPwm, bool state)
{
if (!m_backend)
{
return;
}
for (auto it = m_pwms.begin(); it != m_pwms.end(); ++it)
{
if (it->appPwm == appPwm)
{
m_backend->setPwmHW(it->pwm, state);
}
}
}
void PwmManager::setPwm(EAppPwm appPwm, uint32_t permille)
{
if (!m_backend)
{
return;
}
for (auto it = m_pwms.begin(); it != m_pwms.end(); ++it)
{
if (it->appPwm == appPwm)
{
m_backend->setPwmHW(it->pwm, permille);
}
}
}
void PwmManager::setPwmBlink(EAppPwm appPwm, size_t onMs, size_t offMs)
{
if (!m_backend)
{
return;
}
for (auto it = m_pwms.begin(); it != m_pwms.end(); ++it)
{
if (it->appPwm == appPwm)
{
m_backend->setPwmHWBlink(it->pwm, onMs, offMs);
}
}
}
void PwmManager::setPwmBreath(EAppPwm appPwm, size_t BrathMs)
{
if (!m_backend)
{
return;
}
for (auto it = m_pwms.begin(); it != m_pwms.end(); ++it)
{
if (it->appPwm == appPwm)
{
m_backend->setPwmHWBreath(it->pwm, BrathMs);
}
}
}
void PwmManager::linkPwm(EAppPwm appPwm, size_t pwm)
{
PwmLink link = { .appPwm = appPwm, .pwm = pwm };
m_pwms.insert(link);
}
void PwmManager::unlinkPwm(EAppPwm appPwm)
{
for (auto it = m_pwms.begin(); it != m_pwms.end();)
{
if (it->appPwm == appPwm)
{
it = m_pwms.erase(it);
}
else
{
++it;
}
}
}
void PwmManager::unlinkPwm(size_t pwm)
{
for (auto it = m_pwms.begin(); it != m_pwms.end();)
{
if (it->pwm == pwm)
{
it = m_pwms.erase(it);
}
else
{
++it;
}
}
}
void PwmManager::linkBackend(PwmBackend & backend)
{
if (backend.linkHW())
{
m_backend = &backend;
}
else
{
LOG_ERR("PWM backend not inited!");
}
}
#if CONFIG_WS2812_STRIP
#include <zephyr_ws2812.h>
static WS2812_LED_DEFINE(led_strip);
Ws2812Strip & Ws2812Strip::getInstance()
{
static Ws2812Strip instance;
return instance;
}
bool Ws2812Strip::linkHW()
{
bool result = false;
if (ws2812_led_init(&led_strip))
{
LOG_INF("WS2812 LED inited");
result = true;
}
else
{
LOG_ERR("WS2812 LED not inited!");
}
return result;
}
void Ws2812Strip::setPwmHW(size_t pwm, bool state)
{
LOG_INF("PWM %u turn %s", pwm, state ? "on" : "off");
if (!ws2812_led_set(&led_strip, pwm, state ? WS2812_LED_ON : WS2812_LED_OFF))
{
LOG_WRN("WS2812 LED set pwm %u failed!", pwm);
}
}
void Ws2812Strip::setPwmHW(size_t pwm, uint32_t permille)
{
LOG_INF("PWM %u set %u", pwm, permille);
if (!ws2812_led_set(&led_strip, pwm, WS2812_LED_FIXED, permille))
{
LOG_WRN("WS2812 LED set pwm %u to %u permille failed!", pwm, permille);
}
}
void Ws2812Strip::setPwmHWBlink(size_t pwm, size_t onMs, size_t offMs)
{
LOG_WRN("WS2812 LED setPwmHWBlink not supported");
}
void Ws2812Strip::setPwmHWBreath(size_t pwm, size_t breathMs)
{
LOG_WRN("WS2812 LED setPwmHWBreath not supported");
}
#else
#include <zephyr_pwm_pool.h>
static PWM_POOL_DEFINE(pwm_pool);
PwmPool & PwmPool::getInstance()
{
static PwmPool instance;
return instance;
}
bool PwmPool::linkHW()
{
bool result = false;
if (pwm_pool_init(&pwm_pool))
{
LOG_INF("PWM pool inited");
result = true;
}
else
{
LOG_ERR("PWM pool not inited!");
}
return result;
}
void PwmPool::setPwmHW(size_t pwm, bool state)
{
if (!pwm_pool_set(&pwm_pool, pwm, state ? PWM_ON : PWM_OFF))
{
LOG_WRN("PWM pool set pwm %u failed!", pwm);
}
}
void PwmPool::setPwmHW(size_t pwm, uint32_t permille)
{
if (!pwm_pool_set(&pwm_pool, pwm, PWM_FIXED, permille))
{
LOG_WRN("PWM pool set pwm %u to %u permille failed!", pwm, permille);
}
}
void PwmPool::setPwmHWBlink(size_t pwm, size_t onMs, size_t offMs)
{
if (!pwm_pool_set(&pwm_pool, pwm, PWM_BLINK, K_MSEC(onMs), K_MSEC(offMs)))
{
LOG_WRN("PWM pool set pwm %u blink to (%u-%u)mS failed!", pwm, onMs, offMs);
}
}
void PwmPool::setPwmHWBreath(size_t pwm, size_t breathMs)
{
if (!pwm_pool_set(&pwm_pool, pwm, PWM_BREATH, K_MSEC(breathMs)))
{
LOG_WRN("PWM pool set pwm %u breath to %umS failed!", pwm, breathMs);
}
}
#endif // CONFIG_WS2812_STRIP