/*
* Filename: notificationTask.c
*
* Description: Additional Task that sends a notification the the select
* button is pressed on the SmartRF06 board. This is a dummy
* task to be used as a framework for making a more comlex
* task.
*
* Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
*
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 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.
*
* Neither the name of Texas Instruments Incorporated 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.
*
*/
/*********************************************************************
* INCLUDES
*/
#include <string.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/knl/Clock.h>
#include <ti/sysbios/knl/Semaphore.h>
#include <ti/sysbios/knl/Queue.h>
#include <ti/sysbios/family/arm/cc26xx/PowerCC2650.h>
#include <ti/sysbios/family/arm/m3/Hwi.h>
#include <ti/drivers/pin/PINCC26XX.h>
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/knl/Swi.h>
#include "gatt.h"
#include "inc/hw_memmap.h"
#include "inc/hw_ints.h"
#include "board_key.h"
#include "Board.h"
#include "notificationTask.h"
#include <ti/drivers/lcd/LCDDogm1286.h>
/*********************************************************************
* CONSTANTS
*/
#define NOTIFY_TASK_PRIORITY 1
#ifndef NOTIFY_TASK_STACK_SIZE
#define NOTIFY_TASK_STACK_SIZE 644
#endif
#define TASK_NUM_ATTR_SUPPORTED 1
#define NOTIFY_TASK_SELECT_EVT 0x0001
/*********************************************************************
* LOCAL VARIABLES
*/
static PIN_Config notifySelectPinCfg[] =
{
Board_KEY_SELECT | PIN_GPIO_OUTPUT_DIS | PIN_INPUT_EN | PIN_PULLUP,
PIN_TERMINATE
};
//! \brief PIN State for select pin on SmartRF06 board
static PIN_State notifySelectPinState;
//! \brief PIN Handles for select pin on SmartRF06 board
static PIN_Handle hNotifySelectPin;
// Entity ID globally used to check for source and/or destination of messages
static ICall_EntityID selfEntity;
// Semaphore globally used to post events to the application thread
static ICall_Semaphore sem;
// Clock instances for internal periodic events.
static Clock_Struct periodicClock;
// Task configuration
Task_Struct notifyTask;
Char notifyTaskStack[NOTIFY_TASK_STACK_SIZE];
// events flag for internal application events.
static uint16_t events;
//Dummy Data to send in notificaiton
const UInt32 dataToNotify = 0xAAAA5555;
/*********************************************************************
* LOCAL FUNCTIONS
*/
static void NotificationTask_init( void );
static void NotificationTask_taskFxn(UArg a0, UArg a1);
static void NotificationTask_selectPINHwiFxn(PIN_Handle hPin, PIN_Id pinId);
/*********************************************************************
* PROFILE CALLBACKS
*/
/*********************************************************************
* PUBLIC FUNCTIONS
*/
/*********************************************************************
* @fn NotificationTask_createTask
*
* @brief Task creation function for the Notification Task
*
* @param None.
*
* @return None.
*/
void NotificationTask_createTask(void)
{
Task_Params taskParams;
// Configure task
Task_Params_init(&taskParams);
taskParams.stack = notifyTaskStack;
taskParams.stackSize = NOTIFY_TASK_STACK_SIZE;
taskParams.priority = NOTIFY_TASK_PRIORITY;
Task_construct(¬ifyTask, NotificationTask_taskFxn, &taskParams, NULL);
}
/*********************************************************************
* @fn NotificationTask_init
*
* @brief Called during initialization and contains application
* specific initialization (ie. hardware initialization/setup,
* table initialization, power up notification, etc), and
* profile initialization/setup.
*
* @param None.
*
* @return None.
*/
static void NotificationTask_init(void)
{
// ******************************************************************
// N0 STACK API CALLS CAN OCCUR BEFORE THIS CALL TO ICall_registerApp
// ******************************************************************
// Register the current thread as an ICall dispatcher application
// so that the application can send and receive messages.
ICall_registerApp(&selfEntity, &sem);
//Open the select pin on the board, and register it for interrupts
hNotifySelectPin = PIN_open(¬ifySelectPinState, notifySelectPinCfg);
PIN_registerIntCb(hNotifySelectPin, NotificationTask_selectPINHwiFxn);
PIN_setConfig(hNotifySelectPin,
PIN_BM_IRQ,
Board_KEY_SELECT | PIN_IRQ_BOTHEDGES);
// Enable wakeup
PIN_setConfig(hNotifySelectPin,
PINCC26XX_BM_WAKEUP,
Board_KEY_SELECT | PINCC26XX_WAKEUP_NEGEDGE);
}
/*********************************************************************
* @fn NotificationTask_taskFxn
*
* @brief Application task entry point for the Notification Task.
*
* @param a0, a1 - not used.
*
* @return None.
*/
static void NotificationTask_taskFxn(UArg a0, UArg a1)
{
// Initialize application
NotificationTask_init();
// Application main loop
for (;;)
{
// Waits for a signal to the semaphore associated with the calling thread.
// Note that the semaphore associated with a thread is signaled when a
// message is queued to the message receive queue of the thread or when
// ICall_signal() function is called onto the semaphore.
ICall_Errno errno = ICall_wait(ICALL_TIMEOUT_FOREVER);
if (events & NOTIFY_TASK_SELECT_EVT)
{
//Set up notificaiton data
uint16 len = sizeof(UInt32);
attHandleValueNoti_t noti;
bStatus_t status;
noti.handle = 0x1E;
noti.len = len;
//attempt to allocate payload
noti.pValue = (uint8 *)GATT_bm_alloc( 0, ATT_HANDLE_VALUE_NOTI, GATT_MAX_MTU, &len );
if ( noti.pValue != NULL ) //if allocated
{
//place index
noti.pValue[0] = (dataToNotify >> 24) & 0xFF;
noti.pValue[1] = (dataToNotify >> 16) & 0xFF;
noti.pValue[2] = (dataToNotify >> 8) & 0xFF;
noti.pValue[3] = dataToNotify & 0xFF;
status = GATT_Notification( 0, ¬i, 0 ); //attempt to send
if ( status != SUCCESS ) //if noti not sent
{
GATT_bm_free( (gattMsg_t *)¬i, ATT_HANDLE_VALUE_NOTI );
}
}
else
{
//bleNoResources
asm(" NOP");
}
//Clear the event
events &= ~NOTIFY_TASK_SELECT_EVT;
}
}
}
static void NotificationTask_selectPINHwiFxn(PIN_Handle hPin, PIN_Id pinId)
{
if (sem != NULL)
{
//Set the event and wake up the task
events |= NOTIFY_TASK_SELECT_EVT;
Semaphore_post(sem);
}
}