PWMDevice.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. /*
  2. *
  3. * Copyright (c) 2020 Project CHIP Authors
  4. * All rights reserved.
  5. *
  6. * Licensed under the Apache License, Version 2.0 (the "License");
  7. * you may not use this file except in compliance with the License.
  8. * You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. #include "PWMDevice.h"
  19. #include "AppConfig.h"
  20. #include <lib/support/CodeUtils.h>
  21. #include <zephyr/drivers/pwm.h>
  22. #include <zephyr/kernel.h>
  23. #include <zephyr/logging/log.h>
  24. LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL);
  25. int PWMDevice::Init(const pwm_dt_spec * aPWMDevice, uint8_t aMinLevel, uint8_t aMaxLevel, uint8_t aDefaultLevel)
  26. {
  27. mState = kState_On;
  28. mMinLevel = aMinLevel;
  29. mMaxLevel = aMaxLevel;
  30. mLevel = aDefaultLevel;
  31. mPwmDevice = aPWMDevice;
  32. if (!device_is_ready(mPwmDevice->dev))
  33. {
  34. LOG_ERR("PWM device %s is not ready", mPwmDevice->dev->name);
  35. return -ENODEV;
  36. }
  37. Set(false);
  38. return 0;
  39. }
  40. void PWMDevice::SetCallbacks(PWMCallback aActionInitiatedClb, PWMCallback aActionCompletedClb)
  41. {
  42. mActionInitiatedClb = aActionInitiatedClb;
  43. mActionCompletedClb = aActionCompletedClb;
  44. }
  45. bool PWMDevice::InitiateAction(Action_t aAction, int32_t aActor, uint8_t * aValue)
  46. {
  47. // TODO: this function is called InitiateAction because we want to implement some features such as ramping up here.
  48. bool action_initiated = false;
  49. State_t new_state;
  50. // Initiate On/Off Action only when the previous one is complete.
  51. if (mState == kState_Off && aAction == ON_ACTION)
  52. {
  53. action_initiated = true;
  54. new_state = kState_On;
  55. }
  56. else if (mState == kState_On && aAction == OFF_ACTION)
  57. {
  58. action_initiated = true;
  59. new_state = kState_Off;
  60. }
  61. else if (aAction == LEVEL_ACTION && *aValue != mLevel)
  62. {
  63. action_initiated = true;
  64. if (*aValue == 0)
  65. {
  66. new_state = kState_Off;
  67. }
  68. else
  69. {
  70. new_state = kState_On;
  71. }
  72. }
  73. if (action_initiated)
  74. {
  75. if (mActionInitiatedClb)
  76. {
  77. mActionInitiatedClb(aAction, aActor);
  78. }
  79. if (aAction == ON_ACTION || aAction == OFF_ACTION)
  80. {
  81. Set(new_state == kState_On);
  82. }
  83. else if (aAction == LEVEL_ACTION)
  84. {
  85. mState = new_state;
  86. SetLevel(*aValue);
  87. }
  88. if (mActionCompletedClb)
  89. {
  90. mActionCompletedClb(aAction, aActor);
  91. }
  92. }
  93. return action_initiated;
  94. }
  95. void PWMDevice::SetLevel(uint8_t aLevel)
  96. {
  97. LOG_INF("Setting brightness level to %u", aLevel);
  98. mLevel = aLevel;
  99. ApplyLevel();
  100. }
  101. void PWMDevice::Set(bool aOn)
  102. {
  103. mState = aOn ? kState_On : kState_Off;
  104. ApplyLevel();
  105. }
  106. void PWMDevice::SuppressOutput()
  107. {
  108. pwm_set_pulse_dt(mPwmDevice, 0);
  109. }
  110. void PWMDevice::ApplyLevel()
  111. {
  112. const uint8_t maxEffectiveLevel = mMaxLevel - mMinLevel;
  113. const uint8_t effectiveLevel = mState == kState_On ? chip::min<uint8_t>(mLevel - mMinLevel, maxEffectiveLevel) : 0;
  114. pwm_set_pulse_dt(mPwmDevice,
  115. static_cast<uint32_t>(static_cast<const uint64_t>(mPwmDevice->period) * effectiveLevel / maxEffectiveLevel));
  116. }