How-To: Use Input System Service for Idle Timeout

Last modified by Microchip on 2024/10/30 14:49

Introduction

The Input System Service (ISS) allows other tasks to register as listeners for input events. One such task is the Microchip Graphics Suite (MGS) Harmony Task, which listens to input events through this service.

In some cases, user application code may also need to register as a listener for input events. For instance, monitoring touchscreen activity can help determine if the system has been idle for a certain period and may need to enter low-power mode. Another example is detecting and processing touch gestures at the application level, such as swiping to change screens.

This guide demonstrates how to utilize the Input System Service (ISS) to monitor touch input and manage user inactivity effectively.

MGS Example Project

Refer to the project in GitHub for the example mentioned in this guide.

MGS Simulator Output

The application shows a counter that counts down from 30 seconds when no user input is detected on the screen. When touch input is detected anywhere on the screen, the counter will reset back to 30 seconds. 

When the counter expires to zero, a locked screen dialog box is shown. The screen is unlocked when the unlock button is pressed.

Input System Service Example

MGS Harmony Composer Design

Here is what the design looks like in MGS Harmony Composer.

Selecting the widgets in the Screen Tree window will show the widget in the Screen Designer.

MGS Composer Design

Figure 1: MGS Composer Design

The hidden panel widget pnlLock contains the dialog pop-up box that will show up when the timer expires. This can be shown in MGS Composer by unselecting the Hidden property of pnlLock.

MGS Composer Design 2

Figure 2: MGS Composer Design with Lock Panel Shown

Back to Top

Application Code

There are two types of application code used in this example: the main and the screen application codes.

Note: This example is for a bare-metal configuration. For Real-Time Operating System (RTOS) configurations, the main and screen applications may run as separate tasks.

Appropriate mutual exclusion mechanisms must be implemented by the application developer to protect shared resources.

Main Application Code

The main application code in app.c registers as a listener to the ISS.

First, it declares the ISS listener object and handle.

/* input system service listener object */
static SYS_INP_InputListener APP_inputListener;

/* input system service listener id */
static int32_t APP_inputListenerId;

It also defines the ISS event handler functions for touch down, up, and move events. These functions call the screen Application Programming Interface (API) for resetting the timeout counter value.

/* input system service touch down callback */
static void app_touchDownHandler(const SYS_INP_TouchStateEvent* const evt)
{
   /* Touch Detected reset counter */
    App_Screen0_ResetTimer();
}

/* input system service touch up callback */
static void app_touchUpHandler(const SYS_INP_TouchStateEvent* const evt)
{
   /* Touch Detected reset counter */
    App_Screen0_ResetTimer();
}

/* input system service touch move callback */
static void app_touchMoveHandler(const SYS_INP_TouchMoveEvent* const evt)
{
   /* Touch Detected reset counter */
    App_Screen0_ResetTimer();
}

Then it calls the ISS API to register as a listener to ISS events.

APP_inputListener.handleTouchDown = &app_touchDownHandler;
APP_inputListener.handleTouchUp = &app_touchUpHandler;
APP_inputListener.handleTouchMove = &app_touchMoveHandler;

APP_inputListenerId = SYS_INP_AddListener(&APP_inputListener);
if (APP_inputListenerId >= 0)
{
    appData.state = APP_STATE_SERVICE_TASKS;
}

Since the callbacks are registered in the main application code, these callbacks take effect system-wide and are active regardless of the screen being shown.

Screen Application Code

In the screen application code in app_screen0.c, the screen event callback functions for the screen show/hide/update and unlock button press/release events are defined. 

Screen OnShow and OnHide

When the screen is first shown, the Screen0_OnShow() screen callback function creates a 1-second periodic timer using the Harmony Timer System Service. This periodic timer calls Timer_callback to increment the tickSecs counter.

void Screen0_OnShow(void)
{
   /* Initialize counters */
    tickSecs = 0;
    lastTickSec = 0;

   /* Showing screen, register 1s timer */
    screenTimer = SYS_TIME_CallbackRegisterMS(Timer_Callback,
                 1,
                  SCREEN_TIMER_PERIOD_MS,
                  SYS_TIME_PERIODIC);

   /* Hide lock dialog box at init */
    Screen0_pnlLock->fn->setVisible(Screen0_pnlLock, LE_FALSE);

   //Allocate dynamic string object, must be freed with leString_Delete
   screenCounterString = leDynamicString_New();
    screenCounterString->fn->setFont(screenCounterString, (leFont*) &Font0);
}

This timer is destroyed in Screen0_OnHide when the screen is hidden during a screen transition.

/* Screen On Hide handler */
void Screen0_OnHide(void)
{
   /* Hiding screen, destroy timer */
    SYS_TIME_TimerDestroy(screenTimer);

   /* Free Dynamic string allocations */
    leString_Delete((leString *) screenCounterString);
}

Screen OnUpdate

The Screen0_OnUpdate() function is periodically called by the GFX library. This event callback function is used to monitor the value of tickSecs to show the counter value using the lblCounter label and show the locked screen dialog box when the counter expires.

/* Screen periodic update handler */
void Screen0_OnUpdate(void) {...}
{
   if (lastTickSec != tickSecs)
    {
       char cStrBuff[16];

       /* Update the counter value label */
        snprintf(cStrBuff, 16, "%d\nsecs", tickSecs);

       //Set string data from C-string
       screenCounterString->fn->setFromCStr(screenCounterString, cStrBuff);  

       //Update label widget string
       Screen0_lblCounter->fn->setString(Screen0_lblCounter, (leString *) screenCounterString);

       /* Check if counter has expired */
       if (tickSecs == 0)
        {
           /* Stop Timer */
            SYS_TIME_TimerStart(screenTimer);

           /* Show lock dialog box */
            Screen0_pnlLock->fn->setVisible(Screen0_pnlLock, LE_TRUE);
        }

        lastTickSec = tickSecs;
    }
}

Back to Top

Summary

The example shows how the Input System Service can be used to listen for and receive touch events in the application and process these events to perform application-specific functions. 

Back to Top