Tool/software: TI-RTOS
Hi,
I'm working with BLE project_zero example and making same changes. I'm trying to implement the sensor controller code using a task (scTask) that works when an alert is generated by the Sensor controller, this task (scTask) should pend a semaphore and block waking up a second task that is responsable for initialize the GAP, GATT, ICALL and advertise the device. This, will connect to other device, send the data from the sensors and when disconnected post the semaphore to the initial task. The problem is that when I create one task everythink it's okay, when create both my program stuck. I'm probably missing something!
I will attach the files.
/*********************************************************************
* INCLUDES
*/
#include <string.h>
//#define xdc_runtime_Log_DISABLE_ALL 1 // Add to disable logs from this file
#include <ti/sysbios/knl/Task.h>
#include <ti/sysbios/knl/Semaphore.h>
#include <ti/sysbios/knl/Queue.h>
#include <ti/sysbios/knl/Clock.h>
#include <ti/sysbios/BIOS.h>
#include <ti/drivers/PIN.h>
#include <ti/mw/display/Display.h>
#include <xdc/runtime/Log.h>
#include <xdc/runtime/Diags.h>
// Stack headers
#include <hci_tl.h>
#include <gap.h>
#include <gatt.h>
#include <gapgattserver.h>
#include <gattservapp.h>
#include <osal_snv.h>
#include <gapbondmgr.h>
#include <peripheral.h>
#include <icall_apimsg.h>
#include <devinfoservice.h>
#include "util.h"
#include "Board.h"
#include "project_zero.h"
/* Sensor Controller*/
#include "scif.h"
// Bluetooth Developer Studio services
#include "led_service.h"
#include "button_service.h"
#include "data_service.h"
/*********************************************************************
* CONSTANTS
*/
// Advertising interval when device is discoverable (units of 625us, 160=100ms)
#define DEFAULT_ADVERTISING_INTERVAL 160
// Limited discoverable mode advertises for 30.72s, and then stops
// General discoverable mode advertises indefinitely
#define DEFAULT_DISCOVERABLE_MODE GAP_ADTYPE_FLAGS_GENERAL
// Default pass-code used for pairing.
#define DEFAULT_PASSCODE 000000
// Task configuration
#define PRZ_TASK_PRIORITY 1
#define PRZ_TASK_STACK_SIZE 800
// Internal Events for RTOS application
#define PRZ_STATE_CHANGE_EVT 0x0001
#define PRZ_CHAR_CHANGE_EVT 0x0002
#define PRZ_PERIODIC_EVT 0x0004
#define PRZ_CONN_EVT_END_EVT 0x0008
#define DATA_STRING 15
//Sensor controller
#define BV(n) (1 << (n))
/*********************************************************************
* TYPEDEFS
*/
// Types of messages that can be sent to the user application task from other
// tasks or interrupts. Note: Messages from BLE Stack are sent differently.
typedef enum
{
APP_MSG_SERVICE_WRITE = 0, /* A characteristic value has been written */
APP_MSG_SERVICE_CFG, /* A characteristic configuration has changed */
APP_MSG_UPDATE_CHARVAL, /* Request from ourselves to update a value */
APP_MSG_GAP_STATE_CHANGE, /* The GAP / connection state has changed */
APP_MSG_BUTTON_DEBOUNCED, /* A button has been debounced with new value */
APP_MSG_SEND_PASSCODE, /* A pass-code/PIN is requested during pairing */
APP_MSG_SEND_DATA, /* Usado para sinalizar que uma mensagem vai ser enviada*/
} app_msg_types_t;
// Struct for messages sent to the application task
typedef struct
{
Queue_Elem _elem;
app_msg_types_t type;
uint8_t pdu[];
} app_msg_t;
// Struct for messages about characteristic data
typedef struct
{
uint16_t svcUUID; // UUID of the service
uint16_t dataLen; //
uint8_t paramID; // Index of the characteristic
uint8_t data[]; // Flexible array member, extended to malloc - sizeof(.)
} char_data_t;
// Struct for message about sending/requesting passcode from peer.
typedef struct
{
uint16_t connHandle;
uint8_t uiInputs;
uint8_t uiOutputs;
uint32 numComparison;
} passcode_req_t;
typedef struct
{
uint8_t ready;
uint8_t saveFlag;
} data_manage;
/*********************************************************************
* LOCAL VARIABLES
*/
// 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;
// Queue object used for application messages.
static Queue_Struct applicationMsgQ;
static Queue_Handle hApplicationMsgQ;
// Task configuration
Task_Struct przTask;
Char przTaskStack[PRZ_TASK_STACK_SIZE];
// GAP - SCAN RSP data (max size = 31 bytes)
static uint8_t scanRspData[] =
{
// No scan response data provided.
0x00 // Placeholder to keep the compiler happy.
};
// GAP - Advertisement data (max size = 31 bytes, though this is
// best kept short to conserve power while advertisting)
static uint8_t advertData[] =
{
// Flags; this sets the device to use limited discoverable
// mode (advertises for 30 seconds at a time) or general
// discoverable mode (advertises indefinitely), depending
// on the DEFAULT_DISCOVERY_MODE define.
0x02, // length of this data
GAP_ADTYPE_FLAGS,
DEFAULT_DISCOVERABLE_MODE | GAP_ADTYPE_FLAGS_BREDR_NOT_SUPPORTED,
// complete name
13,
GAP_ADTYPE_LOCAL_NAME_COMPLETE,
'P', 'r', 'o', 'j', 'e', 'c', 't', ' ', 'Z', 'e', 'r', 'o',
};
// GAP GATT Attributes
static uint8_t attDeviceName[GAP_DEVICE_NAME_LEN] = "Project Zero";
// Globals used for ATT Response retransmission
static gattMsgEvent_t *pAttRsp = NULL;
static uint8_t rspTxRetry = 0;
// Semaphore used to wait for Sensor Controller task ALERT event
static Semaphore_Struct semScTaskAlert;
static Semaphore_Struct semTaskManage;
/* humidity and temperature variables*/
static uint16_t measures [40];
static char final [DATA_STRING];
static uint16_t highThreshold;
/* Pin driver handles */
static PIN_Handle ledPinHandle;
/* Global memory storage for a PIN_Config table */
static PIN_State ledPinState;
/*
* Initial LED pin configuration table
* - LEDs Board_LED0 & Board_LED1 are off.
*/
PIN_Config ledPinTable[] = {
Board_LED0 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
Board_LED1 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX,
PIN_TERMINATE
};
/*
* Application button pin configuration table:
* - Buttons interrupts are configured to trigger on falling edge.
*/
PIN_Config buttonPinTable[] = {
Board_BUTTON0 | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_NEGEDGE,
Board_BUTTON1 | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_NEGEDGE,
PIN_TERMINATE
};
// Global display handle
Display_Handle dispHandle;
/*********************************************************************
* LOCAL FUNCTIONS
*/
static void ProjectZero_init( void );
static void sensorController_init(void);
static void ProjectZero_taskFxn(UArg a0, UArg a1);
static void SensorController_taskFxn(UArg a0, UArg a1);
static void user_processApplicationMessage(app_msg_t *pMsg);
static uint8_t ProjectZero_processStackMsg(ICall_Hdr *pMsg);
static uint8_t ProjectZero_processGATTMsg(gattMsgEvent_t *pMsg);
static void ProjectZero_sendAttRsp(void);
static uint8_t ProjectZero_processGATTMsg(gattMsgEvent_t *pMsg);
static void ProjectZero_freeAttRsp(uint8_t status);
static void user_processGapStateChangeEvt(gaprole_States_t newState);
static void user_gapStateChangeCB(gaprole_States_t newState);
static void user_gapBondMgr_passcodeCB(uint8_t *deviceAddr, uint16_t connHandle,
uint8_t uiInputs, uint8_t uiOutputs, uint32 numComparison);
static void user_gapBondMgr_pairStateCB(uint16_t connHandle, uint8_t state,
uint8_t status);
//Integer to String convertion
static char* itoa(uint16_t i, char b[]);
// Generic callback handlers for value changes in services.
static void user_service_ValueChangeCB( uint16_t connHandle, uint16_t svcUuid, uint8_t paramID, uint8_t *pValue, uint16_t len );
static void user_service_CfgChangeCB( uint16_t connHandle, uint16_t svcUuid, uint8_t paramID, uint8_t *pValue, uint16_t len );
// Task context handlers for generated services.
static void user_DataService_ValueChangeHandler(char_data_t *pCharData);
static void user_DataService_CfgChangeHandler(char_data_t *pCharData);
// Task handler for sending notifications.
static void user_updateCharVal(char_data_t *pCharData);
// Utility functions
static void user_enqueueRawAppMsg(app_msg_types_t appMsgType, uint8_t *pData, uint16_t len );
static void user_enqueueCharDataMsg(app_msg_types_t appMsgType, uint16_t connHandle,
uint16_t serviceUUID, uint8_t paramID,
uint8_t *pValue, uint16_t len);
//static void buttonCallbackFxn(PIN_Handle handle, PIN_Id pinId);
static char *Util_convertArrayToHexString(uint8_t const *src, uint8_t src_len,
uint8_t *dst, uint8_t dst_len);
static char *Util_getLocalNameStr(const uint8_t *data);
/*********************************************************************
* PROFILE CALLBACKS
*/
// GAP Role Callbacks
static gapRolesCBs_t user_gapRoleCBs =
{
user_gapStateChangeCB // Profile State Change Callbacks
};
// GAP Bond Manager Callbacks
static gapBondCBs_t user_bondMgrCBs =
{
user_gapBondMgr_passcodeCB, // Passcode callback
user_gapBondMgr_pairStateCB // Pairing / Bonding state Callback
};
/*
* Callbacks in the user application for events originating from BLE services.
*/
// Data Service callback handler.
// The type Data_ServiceCBs_t is defined in data_service.h
static DataServiceCBs_t user_Data_ServiceCBs =
{
.pfnChangeCb = user_service_ValueChangeCB, // Characteristic value change callback handler
.pfnCfgChangeCb = user_service_CfgChangeCB, // Noti/ind configuration callback handler
};
/*********************************************************************
* PUBLIC FUNCTIONS
*/
/*
* @brief Task creation function for the user task.
*
* @param None.
*
* @return None.
*/
void ProjectZero_createTask(void)
{
Task_Params taskParams;
// Configure task
Task_Params_init(&taskParams);
taskParams.stack = przTaskStack;
taskParams.stackSize = PRZ_TASK_STACK_SIZE;
taskParams.priority = 1;
Task_construct(&przTask, ProjectZero_taskFxn, &taskParams, NULL);
}
void ProjectZero_sensorControler(void)
{
Task_Params taskParams;
// Configure task
Task_Params_init(&taskParams);
taskParams.stack = przTaskStack;
taskParams.stackSize = PRZ_TASK_STACK_SIZE;
taskParams.priority = 2;
Task_construct(&przTask, SensorController_taskFxn, &taskParams, NULL);
}
void scCtrlReadyCallback(void) {
Log_info0("Control ready Callback!");
} // scCtrlReadyCallback
void scTaskAlertCallback(void) {
Log_info0("ALERT CALLBACK!");
// Wake up the OS task
Semaphore_post(Semaphore_handle(&semScTaskAlert));
} // scTaskAlertCallback
static void sensorController_init(void)
{
Log_info0("Initialize the hardware, sensor controller and semaphores");
// ******************************************************************
// Hardware initialization
// ******************************************************************
// Open LED pins
ledPinHandle = PIN_open(&ledPinState, ledPinTable);
if(!ledPinHandle) {
Log_error0("Error initializing board LED pins");
Task_exit();
}
// *******************************************************************
// Sensor Controller Initialization
// *******************************************************************
// Create the semaphore used to wait for Sensor Controller ALERT events
Semaphore_Params semParams;
Semaphore_Params_init(&semParams);
semParams.mode = Semaphore_Mode_BINARY;
Semaphore_construct(&semScTaskAlert, 0, &semParams);
// Create a new Semaphore to manage the BLE TASK
Semaphore_Params sem_Params;
Semaphore_Params_init(&sem_Params);
sem_Params.mode = Semaphore_Mode_BINARY;
Semaphore_construct(&semTaskManage, 0, &sem_Params);
}
/*
* @brief Called before the task loop and contains application-specific
* initialization of the BLE stack, hardware setup, power-state
* notification if used, and BLE profile/service initialization.
*
* @param None.
*
* @return None.
*/
static void ProjectZero_init(void)
{
// ******************************************************************
// NO 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 via ICall to Stack.
ICall_registerApp(&selfEntity, &sem);
Log_info0("Initializing the BLE stack and services.");
// Open display. By default this is disabled via the predefined symbol Display_DISABLE_ALL.
dispHandle = Display_open(Display_Type_LCD, NULL);
// Initialize queue for application messages.
// Note: Used to transfer control to application thread from e.g. interrupts.
Queue_construct(&applicationMsgQ, NULL);
hApplicationMsgQ = Queue_handle(&applicationMsgQ);
// ******************************************************************
// BLE Stack initialization
// ******************************************************************
// Setup the GAP Peripheral Role Profile
uint8_t initialAdvertEnable = TRUE; // Advertise on power-up
// By setting this to zero, the device will go into the waiting state after
// being discoverable. Otherwise wait this long [ms] before advertising again.
uint16_t advertOffTime = 0; // miliseconds
// Set advertisement enabled.
GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t),
&initialAdvertEnable);
// Configure the wait-time before restarting advertisement automatically
GAPRole_SetParameter(GAPROLE_ADVERT_OFF_TIME, sizeof(uint16_t),
&advertOffTime);
// Initialize Scan Response data
GAPRole_SetParameter(GAPROLE_SCAN_RSP_DATA, sizeof(scanRspData), scanRspData);
// Initialize Advertisement data
GAPRole_SetParameter(GAPROLE_ADVERT_DATA, sizeof(advertData), advertData);
Log_info1("Name in advertData array: \x1b[33m%s\x1b[0m",
(IArg)Util_getLocalNameStr(advertData));
// Set advertising interval
uint16_t advInt = DEFAULT_ADVERTISING_INTERVAL;
GAP_SetParamValue(TGAP_LIM_DISC_ADV_INT_MIN, advInt);
GAP_SetParamValue(TGAP_LIM_DISC_ADV_INT_MAX, advInt);
GAP_SetParamValue(TGAP_GEN_DISC_ADV_INT_MIN, advInt);
GAP_SetParamValue(TGAP_GEN_DISC_ADV_INT_MAX, advInt);
// Set duration of advertisement before stopping in Limited adv mode.
GAP_SetParamValue(TGAP_LIM_ADV_TIMEOUT, 30); // Seconds
// ******************************************************************
// BLE Bond Manager initialization
// ******************************************************************
uint32_t passkey = 0; // passkey "000000"
uint8_t pairMode = GAPBOND_PAIRING_MODE_WAIT_FOR_REQ;
uint8_t mitm = TRUE;
uint8_t ioCap = GAPBOND_IO_CAP_DISPLAY_ONLY;
uint8_t bonding = TRUE;
GAPBondMgr_SetParameter(GAPBOND_DEFAULT_PASSCODE, sizeof(uint32_t),
&passkey);
GAPBondMgr_SetParameter(GAPBOND_PAIRING_MODE, sizeof(uint8_t), &pairMode);
GAPBondMgr_SetParameter(GAPBOND_MITM_PROTECTION, sizeof(uint8_t), &mitm);
GAPBondMgr_SetParameter(GAPBOND_IO_CAPABILITIES, sizeof(uint8_t), &ioCap);
GAPBondMgr_SetParameter(GAPBOND_BONDING_ENABLED, sizeof(uint8_t), &bonding);
// ******************************************************************
// BLE Service initialization
// ******************************************************************
// Add services to GATT server
GGS_AddService(GATT_ALL_SERVICES); // GAP
GATTServApp_AddService(GATT_ALL_SERVICES); // GATT attributes
DevInfo_AddService(); // Device Information Service
// Set the device name characteristic in the GAP Profile
GGS_SetParameter(GGS_DEVICE_NAME_ATT, GAP_DEVICE_NAME_LEN, attDeviceName);
// Add services to GATT server and give ID of this task for Indication acks.
// LedService_AddService( selfEntity );
// ButtonService_AddService( selfEntity );
DataService_AddService( selfEntity );
// Register callbacks with the generated services that
// can generate events (writes received) to the application
// LedService_RegisterAppCBs( &user_LED_ServiceCBs );
// ButtonService_RegisterAppCBs( &user_Button_ServiceCBs );
DataService_RegisterAppCBs( &user_Data_ServiceCBs );
// Placeholder variable for characteristic intialization
uint8_t initVal[50] = {0};
uint8_t initString[] = "Primeira String a ser guardada e enviada!";
// Initalization of characteristics in Data_Service that can provide data.
//DataService_SetParameter(DS_STRING_ID, sizeof(initString), initString);
DataService_SetParameter(DS_STRING_ID, DS_STRING_LEN, initString);
DataService_SetParameter(DS_STREAM_ID, DS_STREAM_LEN, initVal);
// Start the stack in Peripheral mode.
VOID GAPRole_StartDevice(&user_gapRoleCBs);
// Start Bond Manager
VOID GAPBondMgr_Register(&user_bondMgrCBs);
// Register with GAP for HCI/Host messages
GAP_RegisterForMsgs(selfEntity);
// Register for GATT local events and ATT Responses pending for transmission
GATT_RegisterForMsgs(selfEntity);
}
static void SensorController_taskFxn(UArg arg0, UArg arg1)
{
uint8_t i;
char *str;
data_manage data;
data.ready = 0;
//Sensor Controller Init
sensorController_init();
Log_info0("Project Zero task created");
//ProjectZero_createTask();
// Initialize the Sensor Controller
scifOsalInit();
scifOsalRegisterCtrlReadyCallback(scCtrlReadyCallback);
scifOsalRegisterTaskAlertCallback(scTaskAlertCallback);
scifInit(&scifDriverSetup);
// Set the Sensor Controller task tick interval to 1 second
scifStartRtcTicksNow(0x00010000);
// Configure to trigger interrupt at first result
highThreshold = scifTaskData.i2cHrBufferSensor.cfg.alertThr = DATA_STRING;
scifStartTasksNbl(BV(SCIF_I2C_HR_BUFFER_SENSOR_TASK_ID));
Log_info0("Sensor Controller Task Function");
for(;;)
{
// Wait for an ALERT callback
Semaphore_pend(Semaphore_handle(&semScTaskAlert), BIOS_WAIT_FOREVER);
// Clear the ALERT interrupt source
scifClearAlertIntSource();
if(scifTaskData.i2cHrBufferSensor.state.i2cStatus == 0)
{
Log_warning0("O sistema ja tem valores!");
}
// The HR and TMP value from the SCP
for(i = 0; i<highThreshold; i = i+2)
{
uint16_t hr = scifTaskData.i2cHrBufferSensor.output.samples[i];
uint16_t tmp = scifTaskData.i2cHrBufferSensor.output.samples[i+1];
measures[i] = ((125 * hr)/65536)-6;
if(i == 0)
strcpy(final, itoa(measures[i], str)); //Copy the value to the initial array
else
strcat(final, itoa(measures[i], str));
measures[i+1] = ((175.72 * tmp)/65536)-46.85;
strcat(final, itoa(measures[i+1], str)); // Concatenate the values received
}
Log_info1("Final: %s", final);
//data.ready = 1; //Data is ready - start BLE
Task_sleep(10);
// Caso os dados estejam prontos passa para a task de envio
if(data.ready == 1)
Semaphore_pend(Semaphore_handle(&semTaskManage), BIOS_WAIT_FOREVER);
// Acknowledge the alert event
scifAckAlertEvents();
}
}
/*
* @brief Application task entry point.
*
* Invoked by TI-RTOS when BIOS_start is called. Calls an init function
* and enters an infinite loop waiting for messages.
*
* Messages can be either directly from the BLE stack or from user code
* like Hardware Interrupt (Hwi) or a callback function.
*
* The reason for sending messages to this task from e.g. Hwi's is that
* some RTOS and Stack APIs are not available in callbacks and so the
* actions that may need to be taken is dispatched to this Task.
*
* @param a0, a1 - not used.
*
* @return None.
*/
static void ProjectZero_taskFxn(UArg a0, UArg a1)
{
// Initialize application
ProjectZero_init();
Log_info0("Entrada na task BLE");
// Application main loop
for (;;)
{
Log_warning0("First LOOP message!");
// 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 (errno == ICALL_ERRNO_SUCCESS)
{
ICall_EntityID dest;
ICall_ServiceEnum src;
ICall_HciExtEvt *pMsg = NULL;
// Check if we got a signal because of a stack message
if (ICall_fetchServiceMsg(&src, &dest,
(void **)&pMsg) == ICALL_ERRNO_SUCCESS)
{
uint8 safeToDealloc = TRUE;
if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntity))
{
ICall_Stack_Event *pEvt = (ICall_Stack_Event *)pMsg;
// Check for event flags received (event signature 0xffff)
if (pEvt->signature == 0xffff)
{
// Event received when a connection event is completed
if (pEvt->event_flag & PRZ_CONN_EVT_END_EVT)
{
// Try to retransmit pending ATT Response (if any)
ProjectZero_sendAttRsp();
}
}
else // It's a message from the stack and not an event.
{
// Process inter-task message
safeToDealloc = ProjectZero_processStackMsg((ICall_Hdr *)pMsg);
}
}
if (pMsg && safeToDealloc)
{
ICall_freeMsg(pMsg);
}
}
Task_sleep(10);
// Process messages sent from another task or another context.
while (!Queue_empty(hApplicationMsgQ))
{
app_msg_t *pMsg = Queue_dequeue(hApplicationMsgQ);
// Process application-layer message probably sent from ourselves.
user_processApplicationMessage(pMsg);
// Free the received message.
ICall_free(pMsg);
}
}
}
}
/*
* @brief Handle application messages
*
* These are messages not from the BLE stack, but from the
* application itself.
*
* For example, in a Software Interrupt (Swi) it is not possible to
* call any BLE APIs, so instead the Swi function must send a message
* to the application Task for processing in Task context.
*
* @param pMsg Pointer to the message of type app_msg_t.
*
* @return None.
*/
static void user_processApplicationMessage(app_msg_t *pMsg)
{
char_data_t *pCharData = (char_data_t *)pMsg->pdu;
switch (pMsg->type)
{
case APP_MSG_SERVICE_WRITE: /* Message about received value write */
/* Call different handler per service */
Log_info0("APP_MSG_SERVICE_WRITE");
switch(pCharData->svcUUID) {
case DATA_SERVICE_SERV_UUID:
user_DataService_ValueChangeHandler(pCharData);
break;
}
break;
case APP_MSG_SERVICE_CFG: /* Message about received CCCD write */
Log_info0("APP_MSG_SERVICE_CFG");
/* Call different handler per service */
switch(pCharData->svcUUID) {
case DATA_SERVICE_SERV_UUID:
user_DataService_CfgChangeHandler(pCharData);
break;
}
break;
case APP_MSG_UPDATE_CHARVAL: /* Message from ourselves to send */
Log_info0("APP_MSG_SERVICE_CHARVAL");
user_updateCharVal(pCharData);
break;
case APP_MSG_GAP_STATE_CHANGE: /* Message that GAP state changed */
Log_info0("APP_MSG_SERVICE_CAHNGE");
user_processGapStateChangeEvt( *(gaprole_States_t *)pMsg->pdu );
break;
case APP_MSG_SEND_PASSCODE: /* Message about pairing PIN request */
{
Log_info0("APP_MSG_SEND_PASSCODE");
passcode_req_t *pReq = (passcode_req_t *)pMsg->pdu;
Log_info2("BondMgr Requested passcode. We are %s passcode %06d",
(IArg)(pReq->uiInputs?"Sending":"Displaying"),
DEFAULT_PASSCODE);
// Send passcode response.
GAPBondMgr_PasscodeRsp(pReq->connHandle, SUCCESS, DEFAULT_PASSCODE);
}
break;
case APP_MSG_BUTTON_DEBOUNCED: /* Message from swi about pin change */
{
// Log_info0("APP_MSG_BUTTON_DEBOUNCED");
// button_state_t *pButtonState = (button_state_t *)pMsg->pdu;
// user_handleButtonPress(pButtonState);
}
break;
}
}
/******************************************************************************
*****************************************************************************
*
* Handlers of system/application events deferred to the user Task context.
* Invoked from the application Task function above.
*
* Further down you can find the callback handler section containing the
* functions that defer their actions via messages to the application task.
*
****************************************************************************
*****************************************************************************/
/*
* @brief Process a pending GAP Role state change event.
*
* @param newState - new state
*
* @return None.
*/
static void user_processGapStateChangeEvt(gaprole_States_t newState)
{
switch ( newState )
{
case GAPROLE_STARTED:
{
uint8_t ownAddress[B_ADDR_LEN];
uint8_t systemId[DEVINFO_SYSTEM_ID_LEN];
GAPRole_GetParameter(GAPROLE_BD_ADDR, ownAddress);
// use 6 bytes of device address for 8 bytes of system ID value
systemId[0] = ownAddress[0];
systemId[1] = ownAddress[1];
systemId[2] = ownAddress[2];
// set middle bytes to zero
systemId[4] = 0x00;
systemId[3] = 0x00;
// shift three bytes up
systemId[7] = ownAddress[5];
systemId[6] = ownAddress[4];
systemId[5] = ownAddress[3];
DevInfo_SetParameter(DEVINFO_SYSTEM_ID, DEVINFO_SYSTEM_ID_LEN, systemId);
// Display device address
char *cstr_ownAddress = Util_convertBdAddr2Str(ownAddress);
Log_info1("GAP is started. Our address: \x1b[32m%s\x1b[0m", (IArg)cstr_ownAddress);
}
break;
case GAPROLE_ADVERTISING:
// Initalization of characteristics in Data_Service that can provide data.
//DataService_SetParameter(DS_STRING_ID, sizeof(initString), initString);
//DataService_SetParameter(DS_STRING_ID, DS_STRING_LEN, measures);
Log_info0("Advertising");
break;
case GAPROLE_CONNECTED:
{
uint8_t peerAddress[B_ADDR_LEN];
GAPRole_GetParameter(GAPROLE_CONN_BD_ADDR, peerAddress);
char *cstr_peerAddress = Util_convertBdAddr2Str(peerAddress);
Log_info1("Connected. Peer address: \x1b[32m%s\x1b[0m", (IArg)cstr_peerAddress);
//Once connected save the data the be send
//DataService_SetParameter(DS_STRING_ID, DS_STRING_LEN, data.final);
//memset(final, 0, sizeof(final));
}
break;
case GAPROLE_CONNECTED_ADV:
Log_info0("Connected and advertising");
break;
case GAPROLE_WAITING:
Log_info0("Disconnected / Idle");
break;
case GAPROLE_WAITING_AFTER_TIMEOUT:
Log_info0("Connection timed out");
break;
case GAPROLE_ERROR:
Log_info0("Error");
break;
default:
break;
}
}
/*
* @brief Handle a write request sent from a peer device.
*
* Invoked by the Task based on a message received from a callback.
*
* When we get here, the request has already been accepted by the
* service and is valid from a BLE protocol perspective as well as
* having the correct length as defined in the service implementation.
*
* @param pCharData pointer to malloc'd char write data
*
* @return None.
*/
void user_DataService_ValueChangeHandler(char_data_t *pCharData)
{
// Value to hold the received string for printing via Log, as Log printouts
// happen in the Idle task, and so need to refer to a global/static variable.
static uint8_t received_string[DS_STRING_LEN] = {0};
switch (pCharData->paramID)
{
case DS_STRING_ID:
// Do something useful with pCharData->data here
// -------------------------
// Copy received data to holder array, ensuring NULL termination.
memset(received_string, 0, DS_STRING_LEN);
memcpy(received_string, pCharData->data, DS_STRING_LEN-1);
// Needed to copy before log statement, as the holder array remains after
// the pCharData message has been freed and reused for something else.
Log_info3("Value Change msg: %s %s: %s",
(IArg)"Data Service",
(IArg)"String",
(IArg)received_string);
break;
case DS_STREAM_ID:
Log_info3("Value Change msg: Data Service Stream: %02x:%02x:%02x...",
(IArg)pCharData->data[0],
(IArg)pCharData->data[1],
(IArg)pCharData->data[2]);
// -------------------------
// Do something useful with pCharData->data here
break;
default:
return;
}
}
/*
* @brief Handle a CCCD (configuration change) write received from a peer
* device. This tells us whether the peer device wants us to send
* Notifications or Indications.
*
* @param pCharData pointer to malloc'd char write data
*
* @return None.
*/
void user_DataService_CfgChangeHandler(char_data_t *pCharData)
{
// Cast received data to uint16, as that's the format for CCCD writes.
uint16_t configValue = *(uint16_t *)pCharData->data;
char *configValString;
// Determine what to tell the user
switch(configValue)
{
case GATT_CFG_NO_OPERATION:
configValString = "Noti/Ind disabled";
break;
case GATT_CLIENT_CFG_NOTIFY:
configValString = "Notifications enabled";
break;
case GATT_CLIENT_CFG_INDICATE:
configValString = "Indications enabled";
break;
}
switch (pCharData->paramID)
{
case DS_STREAM_ID:
Log_info3("CCCD Change msg: %s %s: %s",
(IArg)"Data Service",
(IArg)"Stream",
(IArg)configValString);
// -------------------------
// Do something useful with configValue here. It tells you whether someone
// wants to know the state of this characteristic.
// ...
break;
}
}
/*
* @brief Process an incoming BLE stack message.
*
* This could be a GATT message from a peer device like acknowledgement
* of an Indication we sent, or it could be a response from the stack
* to an HCI message that the user application sent.
*
* @param pMsg - message to process
*
* @return TRUE if safe to deallocate incoming message, FALSE otherwise.
*/
static uint8_t ProjectZero_processStackMsg(ICall_Hdr *pMsg)
{
uint8_t safeToDealloc = TRUE;
switch (pMsg->event)
{
case GATT_MSG_EVENT:
// Process GATT message
safeToDealloc = ProjectZero_processGATTMsg((gattMsgEvent_t *)pMsg);
break;
case HCI_GAP_EVENT_EVENT:
{
// Process HCI message
switch(pMsg->status)
{
case HCI_COMMAND_COMPLETE_EVENT_CODE:
// Process HCI Command Complete Event
Log_info0("HCI Command Complete Event received");
break;
default:
break;
}
}
break;
default:
// do nothing
break;
}
return (safeToDealloc);
}
/*
* @brief Process GATT messages and events.
*
* @return TRUE if safe to deallocate incoming message, FALSE otherwise.
*/
static uint8_t ProjectZero_processGATTMsg(gattMsgEvent_t *pMsg)
{
// See if GATT server was unable to transmit an ATT response
if (pMsg->hdr.status == blePending)
{
Log_warning1("Outgoing RF FIFO full. Re-schedule transmission of msg with opcode 0x%02x",
pMsg->method);
// No HCI buffer was available. Let's try to retransmit the response
// on the next connection event.
if (HCI_EXT_ConnEventNoticeCmd(pMsg->connHandle, selfEntity,
PRZ_CONN_EVT_END_EVT) == SUCCESS)
{
// First free any pending response
ProjectZero_freeAttRsp(FAILURE);
// Hold on to the response message for retransmission
pAttRsp = pMsg;
// Don't free the response message yet
return (FALSE);
}
}
else if (pMsg->method == ATT_FLOW_CTRL_VIOLATED_EVENT)
{
// ATT request-response or indication-confirmation flow control is
// violated. All subsequent ATT requests or indications will be dropped.
// The app is informed in case it wants to drop the connection.
// Log the opcode of the message that caused the violation.
Log_error1("Flow control violated. Opcode of offending ATT msg: 0x%02x",
pMsg->msg.flowCtrlEvt.opcode);
}
else if (pMsg->method == ATT_MTU_UPDATED_EVENT)
{
// MTU size updated
Log_info1("MTU Size change: %d bytes", pMsg->msg.mtuEvt.MTU);
}
else
{
// Got an expected GATT message from a peer.
Log_info1("Recevied GATT Message. Opcode: 0x%02x", pMsg->method);
}
// Free message payload. Needed only for ATT Protocol messages
GATT_bm_free(&pMsg->msg, pMsg->method);
// It's safe to free the incoming message
return (TRUE);
}
/*
* Application error handling functions
*****************************************************************************/
/*
* @brief Send a pending ATT response message.
*
* The message is one that the stack was trying to send based on a
* peer request, but the response couldn't be sent because the
* user application had filled the TX queue with other data.
*
* @param none
*
* @return none
*/
static void ProjectZero_sendAttRsp(void)
{
// See if there's a pending ATT Response to be transmitted
if (pAttRsp != NULL)
{
uint8_t status;
// Increment retransmission count
rspTxRetry++;
// Try to retransmit ATT response till either we're successful or
// the ATT Client times out (after 30s) and drops the connection.
status = GATT_SendRsp(pAttRsp->connHandle, pAttRsp->method, &(pAttRsp->msg));
if ((status != blePending) && (status != MSG_BUFFER_NOT_AVAIL))
{
// Disable connection event end notice
HCI_EXT_ConnEventNoticeCmd(pAttRsp->connHandle, selfEntity, 0);
// We're done with the response message
ProjectZero_freeAttRsp(status);
}
else
{
// Continue retrying
Log_warning2("Retrying message with opcode 0x%02x. Attempt %d",
pAttRsp->method, rspTxRetry);
}
}
}
/*
* @brief Free ATT response message.
*
* @param status - response transmit status
*
* @return none
*/
static void ProjectZero_freeAttRsp(uint8_t status)
{
// See if there's a pending ATT response message
if (pAttRsp != NULL)
{
// See if the response was sent out successfully
if (status == SUCCESS)
{
Log_info2("Sent message with opcode 0x%02x. Attempt %d",
pAttRsp->method, rspTxRetry);
}
else
{
Log_error2("Gave up message with opcode 0x%02x. Status: %d",
pAttRsp->method, status);
// Free response payload
GATT_bm_free(&pAttRsp->msg, pAttRsp->method);
}
// Free response message
ICall_freeMsg(pAttRsp);
// Reset our globals
pAttRsp = NULL;
rspTxRetry = 0;
}
}
/******************************************************************************
*****************************************************************************
*
* Handlers of direct system callbacks.
*
* Typically enqueue the information or request as a message for the
* application Task for handling.
*
****************************************************************************
*****************************************************************************/
/*
* Callbacks from the Stack Task context (GAP or Service changes)
*****************************************************************************/
/**
* Callback from GAP Role indicating a role state change.
*/
static void user_gapStateChangeCB(gaprole_States_t newState)
{
Log_info1("(CB) GAP State change: %d, Sending msg to app.", (IArg)newState);
user_enqueueRawAppMsg( APP_MSG_GAP_STATE_CHANGE, (uint8_t *)&newState, sizeof(newState) );
//Caso o dispositivo levar DC faz post do semaphore
if(newState == GAPROLE_WAITING)
Semaphore_post(Semaphore_handle(&semTaskManage));
}
/*
* @brief Passcode callback.
*
* @param connHandle - connection handle
* @param uiInputs - input passcode?
* @param uiOutputs - display passcode?
* @param numComparison - numeric comparison value
*
* @return none
*/
static void user_gapBondMgr_passcodeCB(uint8_t *deviceAddr, uint16_t connHandle,
uint8_t uiInputs, uint8_t uiOutputs, uint32 numComparison)
{
passcode_req_t req =
{
.connHandle = connHandle,
.uiInputs = uiInputs,
.uiOutputs = uiOutputs,
.numComparison = numComparison
};
// Defer handling of the passcode request to the application, in case
// user input is required, and because a BLE API must be used from Task.
user_enqueueRawAppMsg(APP_MSG_SEND_PASSCODE, (uint8_t *)&req, sizeof(req));
}
/*
* @brief Pairing state callback.
*
* @param connHandle - connection handle
* @param state - pairing state
* @param status - pairing status
*
* @return none
*/
static void user_gapBondMgr_pairStateCB(uint16_t connHandle, uint8_t state,
uint8_t status)
{
if (state == GAPBOND_PAIRING_STATE_STARTED)
{
Log_info0("Pairing started");
}
else if (state == GAPBOND_PAIRING_STATE_COMPLETE)
{
if (status == SUCCESS)
{
Log_info0("Pairing completed successfully.");
}
else
{
Log_error1("Pairing failed. Error: %02x", status);
}
}
else if (state == GAPBOND_PAIRING_STATE_BONDED)
{
if (status == SUCCESS)
{
Log_info0("Re-established pairing from stored bond info.");
}
}
}
/**
* Callback handler for characteristic value changes in services.
*/
static void user_service_ValueChangeCB( uint16_t connHandle, uint16_t svcUuid,
uint8_t paramID, uint8_t *pValue,
uint16_t len )
{
// See the service header file to compare paramID with characteristic.
Log_info2("(CB) Characteristic value change: svc(0x%04x) paramID(%d). "
"Sending msg to app.", (IArg)svcUuid, (IArg)paramID);
user_enqueueCharDataMsg(APP_MSG_SERVICE_WRITE, connHandle, svcUuid, paramID,
pValue, len);
}
/**
* Callback handler for characteristic configuration changes in services.
*/
static void user_service_CfgChangeCB( uint16_t connHandle, uint16_t svcUuid,
uint8_t paramID, uint8_t *pValue,
uint16_t len )
{
Log_info2("(CB) Char config change: svc(0x%04x) paramID(%d). "
"Sending msg to app.", (IArg)svcUuid, (IArg)paramID);
user_enqueueCharDataMsg(APP_MSG_SERVICE_CFG, connHandle, svcUuid, paramID, pValue, len);
}
/******************************************************************************
*****************************************************************************
*
* Utility functions
*
****************************************************************************
*****************************************************************************/
/*
* @brief Generic message constructor for characteristic data.
*
* Sends a message to the application for handling in Task context where
* the message payload is a char_data_t struct.
*
* From service callbacks the appMsgType is APP_MSG_SERVICE_WRITE or
* APP_MSG_SERVICE_CFG, and functions running in another context than
* the Task itself, can set the type to APP_MSG_UPDATE_CHARVAL to
* make the user Task loop invoke user_updateCharVal function for them.
*
* @param appMsgType Enumerated type of message being sent.
* @param connHandle GAP Connection handle of the relevant connection
* @param serviceUUID 16-bit part of the relevant service UUID
* @param paramID Index of the characteristic in the service
* @oaram *pValue Pointer to characteristic value
* @param len Length of characteristic data
*/
static void user_enqueueCharDataMsg( app_msg_types_t appMsgType,
uint16_t connHandle,
uint16_t serviceUUID, uint8_t paramID,
uint8_t *pValue, uint16_t len )
{
// Called in Stack's Task context, so can't do processing here.
// Send message to application message queue about received data.
uint16_t readLen = len; // How much data was written to the attribute
// Allocate memory for the message.
// Note: The pCharData message doesn't have to contain the data itself, as
// that's stored in a variable in the service implementation.
//
// However, to prevent data loss if a new value is received before the
// service's container is read out via the GetParameter API is called,
// we copy the characteristic's data now.
app_msg_t *pMsg = ICall_malloc( sizeof(app_msg_t) + sizeof(char_data_t) +
readLen );
Log_info0("SEND MENSAGE TO APP");
if (pMsg != NULL)
{
pMsg->type = appMsgType;
char_data_t *pCharData = (char_data_t *)pMsg->pdu;
pCharData->svcUUID = serviceUUID; // Use 16-bit part of UUID.
pCharData->paramID = paramID;
// Copy data from service now.
memcpy(pCharData->data, pValue, readLen);
// Update pCharData with how much data we received.
pCharData->dataLen = readLen;
// Enqueue the message using pointer to queue node element.
Queue_enqueue(hApplicationMsgQ, &pMsg->_elem);
// Let application know there's a message.
Semaphore_post(sem);
}
}
/*
* @brief Generic message constructor for application messages.
*
* Sends a message to the application for handling in Task context.
*
* @param appMsgType Enumerated type of message being sent.
* @oaram *pValue Pointer to characteristic value
* @param len Length of characteristic data
*/
static void user_enqueueRawAppMsg(app_msg_types_t appMsgType, uint8_t *pData,
uint16_t len)
{
// Allocate memory for the message.
app_msg_t *pMsg = ICall_malloc( sizeof(app_msg_t) + len );
if (pMsg != NULL)
{
pMsg->type = appMsgType;
// Copy data into message
memcpy(pMsg->pdu, pData, len);
// Enqueue the message using pointer to queue node element.
Queue_enqueue(hApplicationMsgQ, &pMsg->_elem);
// Let application know there's a message.
Semaphore_post(sem);
}
}
/*
* @brief Convenience function for updating characteristic data via char_data_t
* structured message.
*
* @note Must run in Task context in case BLE Stack APIs are invoked.
*
* @param *pCharData Pointer to struct with value to update.
*/
static void user_updateCharVal(char_data_t *pCharData)
{
switch(pCharData->svcUUID) {
case LED_SERVICE_SERV_UUID:
LedService_SetParameter(pCharData->paramID, pCharData->dataLen,
pCharData->data);
break;
case BUTTON_SERVICE_SERV_UUID:
ButtonService_SetParameter(pCharData->paramID, pCharData->dataLen,
pCharData->data);
Log_info0("TRATA Button Server UUID");
break;
}
}
//Convertion int to string
static char* itoa(uint16_t i, char b[]){
char const digit[] = "0123456789";
char* p = b;
if(i<0){
*p++ = '-';
i *= -1;
}
int shifter = i;
do{ //Move to where representation ends
++p;
shifter = shifter/10;
}while(shifter);
*p = '\0';
do{ //Move back, inserting digits as u go
*--p = digit[i%10];
i = i/10;
}while(i);
return b;
}
/*
* @brief Convert {0x01, 0x02} to "01:02"
*
* @param src - source byte-array
* @param src_len - length of array
* @param dst - destination string-array
* @param dst_len - length of array
*
* @return array as string
*/
static char *Util_convertArrayToHexString(uint8_t const *src, uint8_t src_len,
uint8_t *dst, uint8_t dst_len)
{
char hex[] = "0123456789ABCDEF";
uint8_t *pStr = dst;
uint8_t avail = dst_len-1;
memset(dst, 0, avail);
while (src_len && avail > 3)
{
if (avail < dst_len-1) { *pStr++ = ':'; avail -= 1; };
*pStr++ = hex[*src >> 4];
*pStr++ = hex[*src++ & 0x0F];
avail -= 2;
src_len--;
}
if (src_len && avail)
*pStr++ = ':'; // Indicate not all data fit on line.
return (char *)dst;
}
/*
* @brief Extract the LOCALNAME from Scan/AdvData
*
* @param data - Pointer to the advertisement or scan response data
*
* @return Pointer to null-terminated string with the adv local name.
*/
static char *Util_getLocalNameStr(const uint8_t *data) {
uint8_t nuggetLen = 0;
uint8_t nuggetType = 0;
uint8_t advIdx = 0;
static char localNameStr[32] = { 0 };
memset(localNameStr, 0, sizeof(localNameStr));
for (advIdx = 0; advIdx < 32;) {
nuggetLen = data[advIdx++];
nuggetType = data[advIdx];
if ( (nuggetType == GAP_ADTYPE_LOCAL_NAME_COMPLETE ||
nuggetType == GAP_ADTYPE_LOCAL_NAME_SHORT) && nuggetLen < 31) {
memcpy(localNameStr, &data[advIdx + 1], nuggetLen - 1);
break;
} else {
advIdx += nuggetLen;
}
}
return localNameStr;
}
/*********************************************************************
*********************************************************************/
/******************************************************************************
@file main.c
@brief main entry of the BLE stack sample application.
Group: WCS, BTS
Target Device: CC2650, CC2640, CC1350
******************************************************************************
Copyright (c) 2013-2016, Texas Instruments Incorporated
All rights reserved.
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.
******************************************************************************
Release Name: ble_sdk_2_02_01_18
Release Date: 2016-05-06 22:17:28
*****************************************************************************/
/*******************************************************************************
* INCLUDES
*/
#include <xdc/runtime/Error.h>
#include <ti/drivers/Power.h>
#include <ti/drivers/power/PowerCC26XX.h>
#include <ti/sysbios/BIOS.h>
#include "icall.h"
#include "hal_assert.h"
#include "bcomdef.h"
#include "peripheral.h"
#include "project_zero.h"
#include <ti/drivers/UART.h>
#include <uart_logs.h>
/* Header files required to enable instruction fetch cache */
#include <inc/hw_memmap.h>
#include <driverlib/vims.h>
#ifndef USE_DEFAULT_USER_CFG
#include "ble_user_config.h"
// BLE user defined configuration
bleUserCfg_t user0Cfg = BLE_USER_CFG;
#endif // USE_DEFAULT_USER_CFG
#include <ti/mw/display/Display.h>
/*******************************************************************************
* MACROS
*/
/*******************************************************************************
* CONSTANTS
*/
/*******************************************************************************
* TYPEDEFS
*/
/*******************************************************************************
* LOCAL VARIABLES
*/
/*******************************************************************************
* GLOBAL VARIABLES
*/
/*******************************************************************************
* EXTERNS
*/
extern void AssertHandler(uint8 assertCause, uint8 assertSubcause);
extern Display_Handle dispHandle;
/*******************************************************************************
* @fn Main
*
* @brief Application Main
*
* input parameters
*
* @param None.
*
* output parameters
*
* @param None.
*
* @return None.
*/
int main()
{
/* Register Application callback to trap asserts raised in the Stack */
RegisterAssertCback(AssertHandler);
PIN_init(BoardGpioInitTable);
#ifndef POWER_SAVING
/* Set constraints for Standby, powerdown and idle mode */
Power_setConstraint(PowerCC26XX_SB_DISALLOW);
Power_setConstraint(PowerCC26XX_IDLE_PD_DISALLOW);
#endif // POWER_SAVING
/* Initialize the RTOS Log formatting and output to UART in Idle thread.
* Note: Define xdc_runtime_Log_DISABLE_ALL to remove all impact of Log.
* Note: NULL as Params gives 115200,8,N,1 and Blocking mode */
UART_init();
UartLog_init(UART_open(Board_UART, NULL));
/* Initialize ICall module */
ICall_init();
/* Start tasks of external images - Priority 5 */
ICall_createRemoteTasks();
/* Kick off profile - Priority 3 */
GAPRole_createTask();
//priority - 2
ProjectZero_sensorControler();
//priority - 1
ProjectZero_createTask();
/* enable interrupts and start SYS/BIOS */
BIOS_start();
return 0;
}
/*******************************************************************************
* @fn AssertHandler
*
* @brief This is the Application's callback handler for asserts raised
* in the stack.
*
* input parameters
*
* @param assertCause - Assert cause as defined in hal_assert.h.
* @param assertSubcause - Optional assert subcause (see hal_assert.h).
*
* output parameters
*
* @param None.
*
* @return None.
*/
void AssertHandler(uint8 assertCause, uint8 assertSubcause)
{
// Open the display if the app has not already done so
if ( !dispHandle )
{
dispHandle = Display_open(Display_Type_LCD, NULL);
}
Display_print0(dispHandle, 0, 0, ">>>STACK ASSERT");
// check the assert cause
switch (assertCause)
{
case HAL_ASSERT_CAUSE_OUT_OF_MEMORY:
Display_print0(dispHandle, 0, 0, "***ERROR***");
Display_print0(dispHandle, 2, 0, ">> OUT OF MEMORY!");
break;
case HAL_ASSERT_CAUSE_INTERNAL_ERROR:
// check the subcause
if (assertSubcause == HAL_ASSERT_SUBCAUSE_FW_INERNAL_ERROR)
{
Display_print0(dispHandle, 0, 0, "***ERROR***");
Display_print0(dispHandle, 2, 0, ">> INTERNAL FW ERROR!");
}
else
{
Display_print0(dispHandle, 0, 0, "***ERROR***");
Display_print0(dispHandle, 2, 0, ">> INTERNAL ERROR!");
}
break;
case HAL_ASSERT_CAUSE_ICALL_ABORT:
Display_print0(dispHandle, 0, 0, "***ERROR***");
Display_print0(dispHandle, 2, 0, ">> ICALL ABORT!");
HAL_ASSERT_SPINLOCK;
break;
default:
Display_print0(dispHandle, 0, 0, "***ERROR***");
Display_print0(dispHandle, 2, 0, ">> DEFAULT SPINLOCK!");
HAL_ASSERT_SPINLOCK;
}
return;
}
/*******************************************************************************
* @fn smallErrorHook
*
* @brief Error handler to be hooked into TI-RTOS.
*
* input parameters
*
* @param eb - Pointer to Error Block.
*
* output parameters
*
* @param None.
*
* @return None.
*/
void smallErrorHook(Error_Block *eb)
{
for (;;);
}
/*******************************************************************************
*/
Best Regards,
Miguel