Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[nrfconnect] Fixed a timer issue on WindowApp #19224

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions examples/window-app/nrfconnect/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,20 @@ requests to start sending the update packages.
An OTA Requestor is a node that wants to download a new firmware image and sends
requests to an OTA Provider to start the update process.

#### Simple Management Protocol

Simple Management Protocol (SMP) is a basic transfer encoding that is used for
device management purposes, including application image management. SMP supports
using different transports, such as Bluetooth LE, UDP, or serial USB/UART.

In this example, the Matter device runs the SMP Server to download the
application update image using the Bluetooth LE transport.

See the
[Building with Device Firmware Upgrade support](#building-with-device-firmware-upgrade-support)
section to learn how to enable SMP and use it for the DFU purpose in this
example.

#### Bootloader

MCUboot is a secure bootloader used for swapping firmware images of different
Expand Down Expand Up @@ -394,6 +408,14 @@ For example, use the following command for `nrf52840dk_nrf52840`:

Support for DFU using Matter OTA is enabled by default.

To enable DFU over Bluetooth LE, run the following command with _build-target_
replaced with the build target name of the Nordic Semiconductor kit you are
using (for example `nrf52840dk_nrf52840`):

```
$ west build -b build-target -- -DCONFIG_CHIP_DFU_OVER_BT_SMP=y
```

To completely disable support for DFU, run the following command with
_build-target_ replaced with the build target name of the Nordic Semiconductor
kit you are using (for example `nrf52840dk_nrf52840`):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@
chosen {
nordic,pm-ext-flash = &mx25r64;
};
};


/ {
/*
* In some default configurations within the nRF Connect SDK,
* e.g. on nRF52840, the chosen zephyr,entropy node is &cryptocell.
Expand All @@ -30,17 +33,15 @@
};

/*
* By default, PWM module is only configured for led0 (LED1 on the board).
* The window-app, however, uses LED2 to show the state of the window cover,
* by using the LED's brightness level.
* Configure LED2 and LED3 to show the state of the
* window cover,by using the LED's brightness level.
*/
aliases {
pwm-led1 = &pwm_led1;
pwm-led2 = &pwm_led2;
};

pwmleds {
compatible = "pwm-leds";
pwm_led1: pwm_led_1 {
pwms = <&pwm0 1 PWM_MSEC(20) PWM_POLARITY_INVERTED>;
};
Expand Down Expand Up @@ -82,15 +83,15 @@
&pinctrl {
pwm0_default_alt: pwm0_default_alt {
group1 {
psels = <NRF_PSEL(PWM_OUT1, 0, 29)>, <NRF_PSEL(PWM_OUT2, 0, 30)>;
psels = <NRF_PSEL(PWM_OUT1, 0, 14)>, <NRF_PSEL(PWM_OUT2, 0, 15)>;
nordic,invert;
};
};

pwm0_sleep_alt: pwm0_sleep_alt {
group1 {
psels = <NRF_PSEL(PWM_OUT1, 0, 29)>, <NRF_PSEL(PWM_OUT2, 0, 30)>;
psels = <NRF_PSEL(PWM_OUT1, 0, 14)>, <NRF_PSEL(PWM_OUT2, 0, 15)>;
low-power-enable;
};
};
};
};
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,16 @@
};

/*
* By default, PWM module is only configured for led0 (LED1 on the board).
* The lighting-app, however, uses LED2 to show the state of the lighting,
* including its brightness level.
* Configure LED2 and LED3 to show the state of the
* window cover,by using the LED's brightness level.
*/
aliases {
pwm-led1 = &pwm_led1;
pwm-led2 = &pwm_led2;
};

pwmleds {
compatible = "pwm-leds";
pwm_led1: pwm_led_1 {
pwms = <&pwm0 1 PWM_MSEC(20) PWM_POLARITY_INVERTED>;
};
Expand Down Expand Up @@ -81,9 +81,9 @@
};
};
};

};


/* Disable unused peripherals to reduce power consumption */
&adc {
status = "disabled";
Expand All @@ -110,14 +110,14 @@
&pinctrl {
pwm0_default_alt: pwm0_default_alt {
group1 {
psels = <NRF_PSEL(PWM_OUT1, 0, 14)>, <NRF_PSEL(PWM_OUT2, 0, 15)>;
psels = <NRF_PSEL(PWM_OUT1, 0, 29)>, <NRF_PSEL(PWM_OUT2, 0, 30)>;
nordic,invert;
};
};

pwm0_sleep_alt: pwm0_sleep_alt {
group1 {
psels = <NRF_PSEL(PWM_OUT1, 0, 14)>, <NRF_PSEL(PWM_OUT2, 0, 15)>;
psels = <NRF_PSEL(PWM_OUT1, 0, 29)>, <NRF_PSEL(PWM_OUT2, 0, 30)>;
low-power-enable;
};
};
Expand Down
22 changes: 21 additions & 1 deletion examples/window-app/nrfconnect/main/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,12 @@ CHIP_ERROR AppTask::Init()
k_timer_init(&sFunctionTimer, &AppTask::FunctionTimerTimeoutCallback, nullptr);
k_timer_user_data_set(&sFunctionTimer, this);

#ifdef CONFIG_MCUMGR_SMP_BT
/* Initialize DFU over SMP */
GetDFUOverSMP().Init(RequestSMPAdvertisingStart);
GetDFUOverSMP().ConfirmNewImage();
#endif

// Initialize CHIP server
SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider());

Expand Down Expand Up @@ -224,6 +230,16 @@ void AppTask::ButtonEventHandler(uint32_t aButtonState, uint32_t aHasChanged)
}
}

#ifdef CONFIG_MCUMGR_SMP_BT
void AppTask::RequestSMPAdvertisingStart(void)
{
AppEvent event;
event.Type = AppEvent::Type::StartSMPAdvertising;
event.Handler = [](AppEvent *) { GetDFUOverSMP().StartBLEAdvertising(); };
PostEvent(&event);
}
#endif

void AppTask::FunctionTimerTimeoutCallback(k_timer * aTimer)
{
if (!aTimer)
Expand Down Expand Up @@ -295,7 +311,11 @@ void AppTask::FunctionHandler(AppEvent * aEvent)

UpdateStatusLED();
CancelTimer();

#ifdef CONFIG_MCUMGR_SMP_BT
GetDFUOverSMP().StartServer();
#else
LOG_INF("Software update is disabled");
#endif
// Change the function to none selected since factory reset has been canceled.
Instance().mMode = OperatingMode::Normal;

Expand Down
44 changes: 20 additions & 24 deletions examples/window-app/nrfconnect/main/WindowCovering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ using namespace chip::app::Clusters::WindowCovering;

static const struct pwm_dt_spec sLiftPwmDevice = PWM_DT_SPEC_GET(DT_ALIAS(pwm_led1));
static const struct pwm_dt_spec sTiltPwmDevice = PWM_DT_SPEC_GET(DT_ALIAS(pwm_led2));
static k_timer sLiftTimer;
static k_timer sTiltTimer;

static constexpr uint32_t sMoveTimeoutMs{ 200 };

WindowCovering::WindowCovering()
Expand All @@ -52,24 +51,6 @@ WindowCovering::WindowCovering()
{
LOG_ERR("Cannot initialize the tilt indicator");
}

k_timer_init(&sLiftTimer, MoveTimerTimeoutCallback, nullptr);
k_timer_init(&sTiltTimer, MoveTimerTimeoutCallback, nullptr);
}

void WindowCovering::MoveTimerTimeoutCallback(k_timer * aTimer)
{
if (!aTimer)
return;

if (aTimer == &sLiftTimer)
{
chip::DeviceLayer::PlatformMgr().ScheduleWork(DriveCurrentLiftPosition);
}
else if (aTimer == &sTiltTimer)
{
chip::DeviceLayer::PlatformMgr().ScheduleWork(DriveCurrentTiltPosition);
}
ArekBalysNordic marked this conversation as resolved.
Show resolved Hide resolved
}

void WindowCovering::DriveCurrentLiftPosition(intptr_t)
Expand Down Expand Up @@ -162,14 +143,29 @@ bool WindowCovering::TargetCompleted(MoveType aMoveType, NPercent100ths aCurrent

void WindowCovering::StartTimer(MoveType aMoveType, uint32_t aTimeoutMs)
{
if (aMoveType == MoveType::LIFT)
MoveType * moveType = chip::Platform::New<MoveType>();
VerifyOrReturn(moveType != nullptr);

*moveType = aMoveType;
(void) chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Milliseconds32(aTimeoutMs), MoveTimerTimeoutCallback,
reinterpret_cast<void *>(moveType));
}

void WindowCovering::MoveTimerTimeoutCallback(chip::System::Layer * systemLayer, void * appState)
{
MoveType * moveType = reinterpret_cast<MoveType *>(appState);
VerifyOrReturn(moveType != nullptr);

if (*moveType == MoveType::LIFT)
{
k_timer_start(&sLiftTimer, K_MSEC(sMoveTimeoutMs), K_NO_WAIT);
chip::DeviceLayer::PlatformMgr().ScheduleWork(WindowCovering::DriveCurrentLiftPosition);
}
else if (aMoveType == MoveType::TILT)
else if (*moveType == MoveType::TILT)
{
k_timer_start(&sTiltTimer, K_MSEC(sMoveTimeoutMs), K_NO_WAIT);
chip::DeviceLayer::PlatformMgr().ScheduleWork(WindowCovering::DriveCurrentTiltPosition);
}

chip::Platform::Delete(moveType);
ArekBalysNordic marked this conversation as resolved.
Show resolved Hide resolved
}

void WindowCovering::DriveCurrentTiltPosition(intptr_t)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class WindowCovering
static chip::Percent100ths CalculateSingleStep(MoveType aMoveType);
static void DriveCurrentLiftPosition(intptr_t);
static void DriveCurrentTiltPosition(intptr_t);
static void MoveTimerTimeoutCallback(k_timer * aTimer);
static void MoveTimerTimeoutCallback(chip::System::Layer * systemLayer, void * appState);
static void DoPostAttributeChange(intptr_t aArg);

MoveType mCurrentUIMoveType;
Expand Down