Commit e0a30c6f authored by Projects's avatar Projects

freertos: State handler (automatically disables the backlight after a period of inactivity).

parent e002454b
......@@ -180,7 +180,8 @@ src/apps/menu_struct.c \
src/main.c \
src/blight_task.c \
src/irq_dispatcher.c \
src/low_power_tick_management.c
src/low_power_tick_management.c \
src/state.c
s_SRC +=
......
......@@ -61,7 +61,7 @@ static bool auto_enabled = false;
static xTimerHandle timer_handle;
///> Currently used index in the lookup table
static uint8_t cur_idx = 0;
static int8_t cur_idx = -1;
static void auto_backlight_task(void *params)
{
......@@ -100,10 +100,14 @@ void auto_backlight_enable(bool enable)
if(xTimerStart(timer_handle, 0) != pdPASS) {
// TODO kernel panic
}
// Select appropriate backlight level
auto_backlight_task(NULL);
} else {
xTimerStop(timer_handle, 0);
cur_idx = -1;
}
auto_enabled = true;
auto_enabled = enable;
}
......@@ -33,10 +33,13 @@
#include <em_gpio.h>
#include <em_burtc.h>
#include "state.h"
static portBASE_TYPE gpio_irq_dispatcher(uint32_t flags)
{
// We have not woken a task at the start of the ISR
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
portBASE_TYPE task_woken1 = pdFALSE;
portBASE_TYPE task_woken2 = pdFALSE;
// Fill the event data
struct event evt;
......@@ -81,13 +84,17 @@ static portBASE_TYPE gpio_irq_dispatcher(uint32_t flags)
break;
// Unexpected event, do not send it
default: return xHigherPriorityTaskWoken;
default: return pdFALSE;
}
// Post the event to the back of the queue
xQueueSendToBackFromISR(appQueue, &evt, &xHigherPriorityTaskWoken);
xQueueSendToBackFromISR(appQueue, &evt, &task_woken1);
// Switch to active state if a button was pressed
if(evt.type == BUTTON_PRESSED)
reset_active_irq(&task_woken2);
return xHigherPriorityTaskWoken;
return task_woken1 || task_woken2;
}
void GPIO_EVEN_IRQHandler(void)
......
......@@ -40,6 +40,7 @@
#include <gfx/ui.h>
#include <apps/app_list.h>
#include "blight_task.h"
#include "state.h"
int main(void)
{
......@@ -61,8 +62,7 @@ int main(void)
lcd_init();
ui_init();
auto_backlight_init();
auto_backlight_enable(true);
state_init();
// Initialize SLEEP driver, no callbacks are used
SLEEP_Init(NULL, NULL);
......
/*
* Copyright (C) 2014 Julian Lewis
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @brief Watch states handling.
*/
#include <FreeRTOS.h>
#include <timers.h>
#include <drivers/backlight.h>
#include "state.h"
#include "blight_task.h"
///> Number of ticks when the watch is considered active since active_reset()
#define ACTIVE_STATE_TICKS 10000
enum watch_state current_state = IDLE;
static xTimerHandle timer_handle;
static void state_handler(enum watch_state state);
static void stop_active(void *params);
void state_init(void)
{
timer_handle = xTimerCreate((signed char*) "active_state",
ACTIVE_STATE_TICKS, pdTRUE,
(void*) 0, stop_active);
reset_active();
}
enum watch_state get_state(void)
{
return current_state;
}
void reset_active(void)
{
xTimerReset(timer_handle, 0);
state_handler(ACTIVE);
}
void reset_active_irq(portBASE_TYPE *task_woken)
{
xTimerResetFromISR(timer_handle, task_woken);
state_handler(ACTIVE);
}
static void stop_active(void *params)
{
(void) params;
xTimerStop(timer_handle, 0);
state_handler(IDLE);
}
static void state_handler(enum watch_state state)
{
if(state == current_state)
return;
switch(state) {
case ACTIVE:
auto_backlight_enable(true);
break;
case IDLE:
auto_backlight_enable(false);
backlight_set_level(0);
// TODO switch frequency? goto sleep?
break;
}
current_state = state;
}
/*
* Copyright (C) 2014 Julian Lewis
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, you may find one here:
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
* or you may search the http://www.gnu.org website for the version 2 license,
* or you may write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
/**
* @brief Watch states handling.
*/
#ifndef STATE_H
#define STATE_H
#include <FreeRTOS.h>
///> Possible states for the watch.
enum watch_state { ACTIVE, IDLE };
/**
* @brief Initializes the state handler.
*/
void state_init(void);
/**
* @brief Returns the current state of watch.
*/
enum watch_state get_state(void);
/**
* @brief Switches to the active state for a period of time.
*/
void reset_active(void);
/**
* @brief Switches to the active state for a period of time (version
* that can be called from interrupt service routines).
* @param task_woken will be set to true if a context switch should
* be performed (@see xTimerReset()).
*/
void reset_active_irq(portBASE_TYPE *task_woken);
#endif /* STATE_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment