Mantis: play power off tune

To play a power off tune, I needed to convert the file to C++, so that I
could use the uORB::Publication.

The current implementation starts playing the power off sound but then
stops it as soon as the button is released.

The problem is mostly that we only get an interrupt when the button is
pressed or released but we don't seem to be able to poll it, at least
not in the current state.
This commit is contained in:
Julian Oes
2022-01-10 23:04:10 -05:00
committed by Daniel Agar
parent 860b23dd17
commit 6960600c28
2 changed files with 15 additions and 1 deletions
+191
View File
@@ -0,0 +1,191 @@
/****************************************************************************
*
* Copyright (c) 2016 PX4 Development Team. All rights reserved.
* Author: David Sidrane <david_s5@nscdg.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* 3. Neither the name PX4 nor the names of its contributors may be
* used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
****************************************************************************/
/**
* @file pwr.c
*
* Board-specific power button functions.
*/
/************************************************************************************
* Included Files
************************************************************************************/
#include <px4_platform_common/px4_config.h>
#include <stdint.h>
#include <stdbool.h>
#include <time.h>
#include <debug.h>
#include <arch/board/board.h>
#include <nuttx/arch.h>
#include <uORB/uORB.h>
#include <uORB/Publication.hpp>
#include <uORB/topics/led_control.h>
#include <uORB/topics/tune_control.h>
#include <arm_arch.h>
#include "board_config.h"
#include <stm32_pwr.h>
extern void led_on(int led);
extern void led_off(int led);
static struct timespec time_down;
static int default_power_button_state_notification(board_power_button_state_notification_e request)
{
// syslog(0,"%d\n", request);
return PWR_BUTTON_RESPONSE_SHUT_DOWN_NOW;
}
static power_button_state_notification_t power_state_notification = default_power_button_state_notification;
/****************************************************************************
* Name: board_pwr_button_down
*
* Description:
* Called to Read the logical state of the active low power button.
*
****************************************************************************/
static bool board_pwr_button_down(void)
{
return 0 == stm32_gpioread(KEY_AD_GPIO);
}
int board_register_power_state_notification_cb(power_button_state_notification_t cb)
{
power_state_notification = cb;
if (board_pwr_button_down() && (time_down.tv_nsec != 0 || time_down.tv_sec != 0)) {
// make sure we don't miss the first event
power_state_notification(PWR_BUTTON_DOWN);
}
return OK;
}
int board_power_off(int status)
{
led_on(BOARD_LED_BLUE);
// disable the interrups
px4_enter_critical_section();
stm32_configgpio(POWER_OFF_GPIO);
while (1);
return 0;
}
static int board_button_irq(int irq, FAR void *context, FAR void *args)
{
uORB::Publication<tune_control_s, tune_control_s::ORB_QUEUE_LENGTH> tune_control_pub{ORB_ID(tune_control)};
if (board_pwr_button_down()) {
led_on(BOARD_LED_RED);
clock_gettime(CLOCK_REALTIME, &time_down);
power_state_notification(PWR_BUTTON_DOWN);
tune_control_s tune_control{};
tune_control.volume = tune_control_s::VOLUME_LEVEL_DEFAULT - 20;
tune_control.tune_id = tune_control_s::TUNE_ID_POWER_OFF;
tune_control.timestamp = hrt_absolute_time();
tune_control_pub.publish(tune_control);
} else {
tune_control_s tune_control{};
tune_control.tune_override = true;
tune_control.timestamp = hrt_absolute_time();
tune_control_pub.publish(tune_control);
power_state_notification(PWR_BUTTON_UP);
led_off(BOARD_LED_RED);
struct timespec now;
clock_gettime(CLOCK_REALTIME, &now);
uint64_t tdown_ms = time_down.tv_sec * 1000 + time_down.tv_nsec / 1000000;
uint64_t tnow_ms = now.tv_sec * 1000 + now.tv_nsec / 1000000;
if (tdown_ms != 0 && (tnow_ms - tdown_ms) >= MS_PWR_BUTTON_DOWN) {
led_on(BOARD_LED_BLUE);
if (power_state_notification(PWR_BUTTON_REQUEST_SHUT_DOWN) == PWR_BUTTON_RESPONSE_SHUT_DOWN_NOW) {
up_mdelay(200);
board_power_off(0);
}
} else {
power_state_notification(PWR_BUTTON_IDEL);
}
}
return OK;
}
/************************************************************************************
* Name: board_pwr_init()
*
* Description:
* Called to configure power control
*
* Input Parameters:
* stage- 0 for boot, 1 for board init
*
************************************************************************************/
void board_pwr_init(int stage)
{
if (stage == 0) {
stm32_configgpio(POWER_ON_GPIO);
stm32_configgpio(KEY_AD_GPIO);
stm32_configgpio(POWER_CHECK_GPIO);
}
if (stage == 1) {
stm32_gpiosetevent(KEY_AD_GPIO, true, true, true, board_button_irq, NULL);
}
}