-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'master' into feature/add-pcc-cluster-implementation
- Loading branch information
Showing
14 changed files
with
1,289 additions
and
20 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,217 @@ | ||
/* | ||
* | ||
* Copyright (c) 2020 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. | ||
*/ | ||
|
||
#include "BoltLockManager.h" | ||
|
||
#include "AppConfig.h" | ||
#include "AppTask.h" | ||
#include "esp_log.h" | ||
#include <freertos/FreeRTOS.h> | ||
static const char * TAG = "BoltLockManager"; | ||
BoltLockManager BoltLockManager::sLock; | ||
|
||
TimerHandle_t sLockTimer; | ||
|
||
int BoltLockManager::Init() | ||
{ | ||
// Create FreeRTOS sw timer for lock timer. | ||
sLockTimer = xTimerCreate("lockTmr", // Just a text name, not used by the RTOS kernel | ||
1, // == default timer period (mS) | ||
false, // no timer reload (==one-shot) | ||
(void *) this, // init timer id = lock obj context | ||
TimerEventHandler // timer callback handler | ||
); | ||
|
||
if (sLockTimer == NULL) | ||
{ | ||
ESP_LOGE(TAG, "sLockTimer timer create failed"); | ||
return CHIP_ERROR_MAX; | ||
} | ||
|
||
mState = kState_LockingCompleted; | ||
mAutoLockTimerArmed = false; | ||
mAutoRelock = false; | ||
mAutoLockDuration = 0; | ||
|
||
return CHIP_NO_ERROR; | ||
} | ||
|
||
void BoltLockManager::SetCallbacks(Callback_fn_initiated aActionInitiated_CB, Callback_fn_completed aActionCompleted_CB) | ||
{ | ||
mActionInitiated_CB = aActionInitiated_CB; | ||
mActionCompleted_CB = aActionCompleted_CB; | ||
} | ||
|
||
bool BoltLockManager::IsActionInProgress() | ||
{ | ||
return (mState == kState_LockingInitiated || mState == kState_UnlockingInitiated); | ||
} | ||
|
||
bool BoltLockManager::IsUnlocked() | ||
{ | ||
return (mState == kState_UnlockingCompleted); | ||
} | ||
|
||
void BoltLockManager::SetAutoLockDuration(uint32_t aDurationInSecs) | ||
{ | ||
mAutoLockDuration = aDurationInSecs; | ||
} | ||
|
||
bool BoltLockManager::InitiateAction(int32_t aActor, Action_t aAction) | ||
{ | ||
bool action_initiated = false; | ||
State_t new_state; | ||
// Initiate Lock/Unlock Action only when the previous one is complete. | ||
if (mState == kState_LockingCompleted && aAction == UNLOCK_ACTION) | ||
{ | ||
action_initiated = true; | ||
|
||
new_state = kState_UnlockingInitiated; | ||
} | ||
else if (mState == kState_UnlockingCompleted && aAction == LOCK_ACTION) | ||
{ | ||
action_initiated = true; | ||
|
||
new_state = kState_LockingInitiated; | ||
} | ||
|
||
if (action_initiated) | ||
{ | ||
if (mAutoLockTimerArmed && new_state == kState_LockingInitiated) | ||
{ | ||
// If auto lock timer has been armed and someone initiates locking, | ||
// cancel the timer and continue as normal. | ||
mAutoLockTimerArmed = false; | ||
|
||
CancelTimer(); | ||
} | ||
|
||
StartTimer(ACTUATOR_MOVEMENT_PERIOS_MS); | ||
|
||
// Since the timer started successfully, update the state and trigger callback | ||
mState = new_state; | ||
|
||
if (mActionInitiated_CB) | ||
{ | ||
mActionInitiated_CB(aAction, aActor); | ||
} | ||
} | ||
|
||
return action_initiated; | ||
} | ||
|
||
void BoltLockManager::StartTimer(uint32_t aTimeoutMs) | ||
{ | ||
if (xTimerIsTimerActive(sLockTimer)) | ||
{ | ||
ESP_LOGI(TAG, "app timer already started!"); | ||
CancelTimer(); | ||
} | ||
|
||
// timer is not active, change its period to required value (== restart). | ||
// FreeRTOS- Block for a maximum of 100 ticks if the change period command | ||
// cannot immediately be sent to the timer command queue. | ||
if (xTimerChangePeriod(sLockTimer, (aTimeoutMs / portTICK_PERIOD_MS), 100) != pdPASS) | ||
{ | ||
ESP_LOGI(TAG, "sLockTimer timer start() failed"); | ||
return; | ||
} | ||
} | ||
|
||
void BoltLockManager::CancelTimer(void) | ||
{ | ||
if (xTimerStop(sLockTimer, 0) == pdFAIL) | ||
{ | ||
ESP_LOGI(TAG, "Lock timer timer stop() failed"); | ||
return; | ||
} | ||
} | ||
void BoltLockManager::TimerEventHandler(TimerHandle_t xTimer) | ||
{ | ||
// Get lock obj context from timer id. | ||
BoltLockManager * lock = static_cast<BoltLockManager *>(pvTimerGetTimerID(xTimer)); | ||
|
||
// The timer event handler will be called in the context of the timer task | ||
// once sLockTimer expires. Post an event to apptask queue with the actual handler | ||
// so that the event can be handled in the context of the apptask. | ||
AppEvent event; | ||
event.Type = AppEvent::kEventType_Timer; | ||
event.TimerEvent.Context = lock; | ||
if (lock->mAutoLockTimerArmed) | ||
{ | ||
event.Handler = AutoReLockTimerEventHandler; | ||
} | ||
else | ||
{ | ||
event.Handler = ActuatorMovementTimerEventHandler; | ||
} | ||
GetAppTask().PostEvent(&event); | ||
} | ||
|
||
void BoltLockManager::AutoReLockTimerEventHandler(AppEvent * aEvent) | ||
{ | ||
BoltLockManager * lock = static_cast<BoltLockManager *>(aEvent->TimerEvent.Context); | ||
int32_t actor = 0; | ||
|
||
// Make sure auto lock timer is still armed. | ||
if (!lock->mAutoLockTimerArmed) | ||
{ | ||
return; | ||
} | ||
|
||
lock->mAutoLockTimerArmed = false; | ||
|
||
ESP_LOGI(TAG, "Auto Re-Lock has been triggered!"); | ||
|
||
lock->InitiateAction(actor, LOCK_ACTION); | ||
} | ||
|
||
void BoltLockManager::ActuatorMovementTimerEventHandler(AppEvent * aEvent) | ||
{ | ||
Action_t actionCompleted = INVALID_ACTION; | ||
|
||
BoltLockManager * lock = static_cast<BoltLockManager *>(aEvent->TimerEvent.Context); | ||
|
||
if (lock->mState == kState_LockingInitiated) | ||
{ | ||
lock->mState = kState_LockingCompleted; | ||
actionCompleted = LOCK_ACTION; | ||
} | ||
else if (lock->mState == kState_UnlockingInitiated) | ||
{ | ||
lock->mState = kState_UnlockingCompleted; | ||
actionCompleted = UNLOCK_ACTION; | ||
} | ||
|
||
if (actionCompleted != INVALID_ACTION) | ||
{ | ||
if (lock->mActionCompleted_CB) | ||
{ | ||
lock->mActionCompleted_CB(actionCompleted); | ||
} | ||
|
||
if (lock->mAutoRelock && actionCompleted == UNLOCK_ACTION) | ||
{ | ||
// Start the timer for auto relock | ||
lock->StartTimer(lock->mAutoLockDuration * 1000); | ||
|
||
lock->mAutoLockTimerArmed = true; | ||
|
||
ESP_LOGI(TAG, "Auto Re-lock enabled. Will be triggered in %u seconds", lock->mAutoLockDuration); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
/* | ||
* | ||
* Copyright (c) 2020 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. | ||
*/ | ||
|
||
#include "Button.h" | ||
#include "AppTask.h" | ||
|
||
#include "AppConfig.h" | ||
|
||
esp_err_t Button::Init(gpio_num_t gpioNum, uint16_t debouncePeriod) | ||
{ | ||
esp_err_t err; | ||
|
||
mGPIONum = gpioNum; | ||
mDebouncePeriod = debouncePeriod / portTICK_PERIOD_MS; | ||
mState = false; | ||
mLastPolledState = false; | ||
|
||
err = gpio_set_direction(gpioNum, GPIO_MODE_INPUT); | ||
SuccessOrExit(err); | ||
|
||
exit: | ||
return err; | ||
} | ||
|
||
bool Button::Poll() | ||
{ | ||
uint32_t now = xTaskGetTickCount(); | ||
|
||
bool newState = gpio_get_level(mGPIONum); | ||
|
||
if (newState != mLastPolledState) | ||
{ | ||
mLastPolledState = newState; | ||
mLastReadTime = now; | ||
} | ||
|
||
else if (newState != mState && (now - mLastReadTime) >= mDebouncePeriod) | ||
{ | ||
mState = newState; | ||
mPrevStateDur = now - mStateStartTime; | ||
mStateStartTime = now; | ||
return true; | ||
} | ||
|
||
return false; | ||
} | ||
|
||
uint32_t Button::GetStateDuration() | ||
{ | ||
return (xTaskGetTickCount() - mStateStartTime) * portTICK_PERIOD_MS; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.