Part Number: CC2650STK
Tool/software: Code Composer Studio
Hi all,
I am implementing the sensortag Accelerometer in the simple_peripheral project of the sensortag, so i copied a few needed files to the root of the simple_peripheral_cc2650stk_app project.
I have modifiied the sensortag_mov.c and created the cadeira.c file so it would do what i need.
The problem is, now always that start debugging the project, it crashes in the void abort(void) function at the exit.c file, it says that is an (ABORT - ABNORMAL PROGRAM TERMINATION. CURRENTLY JUST HALTS EXECUTION. )
Please someone knows what is going on? What could be the reasons for this to happen?
sensortag_mov.c file
/******************************************************************************
@file sensortag_mov.c
@brief This file contains the Movement Processor sub-application. It uses the
MPU-9250 Wake-on-movement feature to allow the
MPU to turn off the gyroscope and magnetometer when no activity is
detected.
Group: WCS, BTS
Target Device: CC2650, CC2640, CC1350
******************************************************************************
Copyright (c) 2015-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-10-26 15:20:04
*****************************************************************************/
#ifndef EXCLUDE_MOV
/*********************************************************************
* INCLUDES
*/
#include <ti/sysbios/knl/Semaphore.h>
#include <ti/sysbios/knl/Queue.h>
#include "gatt.h"
#include "gattservapp.h"
#include "board.h"
#include "sensortag_mov.h"
#include "SensorMpu9250.h"
#include "SensorTagTest.h"
#include "SensorUtil.h"
#include "util.h"
#include "string.h"
#include "cadeira.h"
#include "simple_peripheral.h"
extern void SimpleBLEPeripheral_mexeu();
/*********************************************************************
* MACROS
*/
#define MOVEMENT_INACT_CYCLES (MOVEMENT_INACT_TIMEOUT * \
(10000/sensorPeriod) / 10)
/*********************************************************************
* CONSTANTS and MACROS
*/
// How often to perform sensor reads (milliseconds)
#define SENSOR_DEFAULT_PERIOD 1000
// Length of the data for this sensor
#define SENSOR_DATA_LEN MOVEMENT_DATA_LEN
// Event flag for this sensor
#define SENSOR_EVT ST_GYROSCOPE_SENSOR_EVT
// Movement task states
#define APP_STATE_ERROR 0xFF
#define APP_STATE_OFF 0
#define APP_STATE_IDLE 1
#define APP_STATE_ACTIVE 2
// Movement task configuration
#define MOVEMENT_INACT_TIMEOUT 10 // 10 seconds
#define GYR_SHAKE_THR 10.0
#define WOM_THR 50
// Configuration bit-masks (bits 0-6 defined in sensor_mpu9250.h)
#define MOV_WOM_ENABLE 0x0080
#define MOV_MASK_WOM_THRESHOLD 0x3C00 // TBD
#define MOV_MASK_INACT_TIMEOUT 0xC000 // TBD
/*********************************************************************
* TYPEDEFS
*/
/*********************************************************************
* GLOBAL VARIABLES
*/
/*********************************************************************
* EXTERNAL VARIABLES
*/
/*********************************************************************
* EXTERNAL FUNCTIONS
*/
/*********************************************************************
* LOCAL VARIABLES
*/
static Clock_Struct periodicClock;
static uint16_t sensorPeriod;
static volatile bool sensorReadScheduled;
//static uint8_t sensorData[SENSOR_DATA_LEN];
static volatile uint8_t mpuWom = 0;
// Application state variables
// MPU config:
// bit 0-2: accelerometer enable(z,y,x)
// bit 3-5: gyroscope enable (z,y,x)
// bit 6: magnetometer enable
// bit 7: WOM enable
// bit 8-9: accelerometer range (2,4,8,16)
static uint16_t mpuConfig;
//static uint8_t appState;
//static volatile bool mpuDataRdy;
//bool mpuDataRdy;
volatile bool mpuDataRdy;
static uint8_t movThreshold;
static volatile uint8_t mpuIntStatus;
//static bool shakeDetected;
//static bool test;
//static uint8_t nMotions;
//static uint32_t nActivity;
/*********************************************************************
* LOCAL FUNCTIONS
*/
static void sensorChangeCB(uint8_t paramID);
static void initCharacteristicValue(uint8_t paramID, uint8_t value,
uint8_t paramLen);
static void SensorTagMov_clockHandler(UArg arg);
static void appStateSet(uint8_t newState);
static void SensorTagMov_processInterrupt(void);
/*********************************************************************
* PROFILE CALLBACKS
*/
//static sensorCBs_t sensorCallbacks =
//{
// sensorChangeCB, // Characteristic value change callback
//};
/*********************************************************************
* PUBLIC FUNCTIONS
*/
/*********************************************************************
* @fn SensorTagMov_init
*
* @brief Initialization function for the SensorTag movement sub-application
*
* @param none
*
* @return none
*/
void SensorTagMov_init(void)
{
// Add service
// Movement_addService();
// Register callbacks with profile
// Movement_registerAppCBs(&sensorCallbacks);
// Initialize the module state variables
mpuConfig = 0x00;// ST_CFG_SENSOR_DISABLE
sensorPeriod = SENSOR_DEFAULT_PERIOD;
sensorReadScheduled = false;
mpuConfig = 0x01; // ST_CFG_SENSOR_ENABLE
appStateSet(APP_STATE_ACTIVE);
// appState = APP_STATE_OFF;
// nMotions = 0;
if (SensorMpu9250_init())
{
// SensorTagMov_reset();
SensorMpu9250_registerCallback(SensorTagMov_processInterrupt);
}
SensorMpu9250_enableWom(movThreshold);
// // Initialize characteristics
// initCharacteristicValue(SENSOR_PERI,
// SENSOR_DEFAULT_PERIOD / SENSOR_PERIOD_RESOLUTION,
// sizeof(uint8_t));
//
// Create continuous clock for internal periodic events.
Util_constructClock(&periodicClock, SensorTagMov_clockHandler,
10000, 0, false, 0);
}
/*********************************************************************
* @fn SensorTagMov_processSensorEvent
*
* @brief SensorTag Movement sensor event processor.
*
* @param none
*
* @return none
*/
void SensorTagMov_processSensorEvent(void)
{
#if 0
if (sensorReadScheduled)
{
uint8_t axes;
axes = mpuConfig & MPU_AX_ALL;
if ((axes != ST_CFG_SENSOR_DISABLE) && (axes != ST_CFG_ERROR))
{
// Get interrupt status (clears interrupt)
mpuIntStatus = SensorMpu9250_irqStatus(); //Check if Wake On Motion Has Ocurred
// Process gyro and accelerometer
if (mpuDataRdy || appState == APP_STATE_ACTIVE)
{
if (mpuIntStatus & MPU_MOVEMENT)
{
// Motion detected (small filter)
nMotions++;
test = SensorMpu9250_accRead((uint16_t*)&sensorData[6]);
if (nMotions == 2)
{
nActivity = MOVEMENT_INACT_CYCLES;
}
}
else if (mpuIntStatus & MPU_DATA_READY)
{
// Read gyro data
SensorMpu9250_gyroRead((uint16_t*)sensorData);
// Read accelerometer data
SensorMpu9250_accRead((uint16_t*)&sensorData[6]);
if (shakeDetected)
{
// Motion detected by gyro
nActivity = MOVEMENT_INACT_CYCLES;
shakeDetected = false;
}
}
mpuDataRdy = false;
if (appState == APP_STATE_ACTIVE && !!(mpuConfig & MPU_AX_MAG))
{
uint8_t status;
status = SensorMpu9250_magRead((int16_t*)&sensorData[12]);
// Always measure magnetometer (not interrupt driven)
if (status == MAG_BYPASS_FAIL)
{
// Idle on error
nActivity = 0;
appState = APP_STATE_ERROR;
}
else if (status != MAG_STATUS_OK)
{
SensorMpu9250_magReset();
}
}
}
if (nActivity>0)
{
if (appState != APP_STATE_ACTIVE)
{
// Transition to active state
appState = APP_STATE_ACTIVE;
nMotions = 0;
if (SensorMpu9250_reset())
{
SensorMpu9250_enable(axes);
//SensorMpu9250_enable(0b0001110100000000);
}
}
if (mpuConfig & MOV_WOM_ENABLE)
{
nActivity--;
}
// Send data
Movement_setParameter(SENSOR_DATA, SENSOR_DATA_LEN, sensorData);
}
else
{
if (appState != APP_STATE_IDLE)
{
// Transition from active to idle state
nMotions = 0;
appState = APP_STATE_IDLE;
if (SensorMpu9250_reset())
{
SensorMpu9250_enableWom(movThreshold);
}
}
}
}
sensorReadScheduled = false;
}
#endif
#if 1
if (mpuWom) {
mpuWom = 0;
mpuIntStatus = SensorMpu9250_irqStatus();
// liga o led
// arma (ou reseta) o timer de 10s (MovementTimeout)
if (mpuIntStatus & MPU_MOVEMENT)
{
}
}
#endif
}
/*********************************************************************
* @fn SensorTagMov_processCharChangeEvt
*
* @brief SensorTag Movement event handling
*
* @param paramID - identifies which characteristic has changed
*
* @return none
*/
void SensorTagMov_processCharChangeEvt(uint8_t paramID)
{
#if 0
uint16_t newCfg;
uint8_t newValue8;
switch (paramID)
{
case SENSOR_CONF:
if ((SensorTag_testResult() & SENSOR_MOV_TEST_BM) == 0)
{
mpuConfig = ST_CFG_ERROR;
}
if (mpuConfig != ST_CFG_ERROR)
{
Movement_getParameter(SENSOR_CONF, &newCfg);
if ((newCfg & MPU_AX_ALL) == ST_CFG_SENSOR_DISABLE)
{
// All axes off, turn off device power
mpuConfig = newCfg;
appStateSet(APP_STATE_OFF);
}
else
{
// Some axes on; power up and activate MPU
mpuConfig = newCfg;
appStateSet(APP_STATE_ACTIVE);
if (SensorMpu9250_powerIsOn())
{
DELAY_MS(5);
mpuConfig = newCfg | (SensorMpu9250_accReadRange() << 8);
}
}
Movement_setParameter(SENSOR_CONF, sizeof(mpuConfig), (uint8_t*)&mpuConfig);
}
else
{
// Make sure the previous characteristics value is restored
initCharacteristicValue(SENSOR_CONF, mpuConfig, sizeof(mpuConfig));
}
// Data initially zero
initCharacteristicValue(SENSOR_DATA, 0, SENSOR_DATA_LEN);
break;
case SENSOR_PERI:
Movement_getParameter(SENSOR_PERI, &newValue8);
sensorPeriod = newValue8 * SENSOR_PERIOD_RESOLUTION;
Util_rescheduleClock(&periodicClock,sensorPeriod);
break;
default:
// Should not get here
break;
}
#endif
}
/*********************************************************************
* @fn SensorTagMov_reset
*
* @brief Reset characteristics and disable sensor
*
* @param none
*
* @return none
*/
void SensorTagMov_reset(void)
{
// initCharacteristicValue(SENSOR_DATA, 0, SENSOR_DATA_LEN);
mpuConfig = 0x00 | (ACC_RANGE_8G << 8); // ST_CFG_SENSOR_DISABLE
// Movement_setParameter(SENSOR_CONF, sizeof(mpuConfig), (uint8_t*)&mpuConfig);
// Remove power from the MPU
appStateSet(APP_STATE_OFF);
}
/*********************************************************************
* Private functions
*/
/*********************************************************************
* @fn SensorTagMov_processInterrupt
*
* @brief Interrupt handler for MPU
*
* @param none
*
* @return none
*/
static void SensorTagMov_processInterrupt(void)
{
// Wake up the application thread
Util_stopClock(&periodicClock);
Util_startClock(&periodicClock);
mpuWom = 1;
PIN_setOutputValue(hGpioPin,Board_LED1, Board_LED_ON);
PIN_setOutputValue(hGpioPin,Board_LED2, Board_LED_ON);
SimpleBLEPeripheral_mexeu();
// mpuDataRdy = true;
// sensorReadScheduled = true;
Semaphore_post(sem);
}
/*********************************************************************
* @fn SensorTagMov_clockHandler
*
* @brief Handler function for clock time-outs.
*
* @param arg - not used
*
* @return none
*/
static void SensorTagMov_clockHandler(UArg arg)
{
// Schedule readout periodically
//apaga o led
PIN_setOutputValue(hGpioPin,Board_LED1, Board_LED_OFF);
PIN_setOutputValue(hGpioPin,Board_LED2, Board_LED_OFF);
//mpuDataRdy = false;
// uint8_t TempAdvertEnable = FALSE;
// GAPRole_TerminateConnection();
// GAPRole_SetParameter(GAPROLE_ADVERT_ENABLED, sizeof(uint8_t), &TempAdvertEnable ) ;
// sensorReadScheduled = true;
Semaphore_post(sem);
}
/*********************************************************************
* @fn sensorChangeCB
*
* @brief Callback from Movement Service indicating a value change
*
* @param paramID - parameter ID of the value that was changed.
*
* @return none
*/
static void sensorChangeCB(uint8_t paramID)
{
// Wake up the application thread
// SensorTag_charValueChangeCB(0x04, paramID);
}
/*********************************************************************
* @fn initCharacteristicValue
*
* @brief Initialize a characteristic value
*
* @param paramID - parameter ID of the value is to be cleared
*
* @param value - value to initialize with
*
* @param paramLen - length of the parameter
*
* @return none
*/
static void initCharacteristicValue(uint8_t paramID, uint8_t value,
uint8_t paramLen)
{
// memset(sensorData,value,paramLen);
// Movement_setParameter(paramID, paramLen, sensorData);
}
/*******************************************************************************
* @fn appStateSet
*
* @brief Set the application state
*
*/
static void appStateSet(uint8_t newState)
{
#if 0
if (newState == APP_STATE_OFF)
{
appState = APP_STATE_OFF;
SensorMpu9250_enable(0);
SensorMpu9250_powerOff();
// Stop scheduled data measurements
Util_stopClock(&periodicClock);
}
if (newState == APP_STATE_ACTIVE || newState == APP_STATE_IDLE)
{
appState = APP_STATE_ACTIVE;
nActivity = MOVEMENT_INACT_CYCLES;
movThreshold = WOM_THR;
mpuIntStatus = 0;
shakeDetected = false;
mpuDataRdy = false;
SensorMpu9250_powerOn();
// SensorMpu9250_enable(mpuConfig & 0xFF);
SensorMpu9250_enable(0b0001110100000000);
if (newState == APP_STATE_ACTIVE)
{
// Start scheduled data measurements
Util_startClock(&periodicClock);
}
else
{
// Stop scheduled data measurements
Util_stopClock(&periodicClock);
}
}
#endif
}
#endif // EXCLUDE_MOV
/*********************************************************************
*********************************************************************/
cadeira.c file
/*
* cadeira.c
*
* Created on: 26 de jun de 2017
* Author: Nicholas
*/
/********************************************************************************
* INCLUDES
*/
#include <string.h>
#include <xdc/std.h>
#include <xdc/runtime/System.h>
#include <ti/sysbios/BIOS.h>
#include <ti/sysbios/knl/Clock.h>
#include <ti/sysbios/knl/Semaphore.h>
#include <ti/sysbios/knl/Queue.h>
#include <ti/sysbios/knl/Task.h>
#include <ICall.h>
#include "gatt.h"
#include "hci.h"
#include "gapgattserver.h"
#include "gattservapp.h"
#include "gapbondmgr.h"
#include "osal_snv.h"
#include "util.h"
#include "icall_apimsg.h"
#include "cadeira.h"
//#include "../Middleware/sensors/SensorI2C.h"
#include "SensorI2C.h"
#include "sensortag_mov.h"
#include "Board.h"
#include "ICall.h"
#include "peripheral.h"
// Task configuration
#define ST_TASK_PRIORITY 1
#ifndef ST_TASK_STACK_SIZE
// Stack size may be overridden by project settings
#define ST_TASK_STACK_SIZE 700
#endif
static void Cadeira_taskFxn(UArg a0, UArg a1);
// Queue object used for app messages
static Queue_Struct appMsg;
static Queue_Handle appMsgQueue;
/*******************************************************************************
* GLOBAL VARIABLES
*/
// Profile state and parameters
gaprole_States_t gapProfileState = GAPROLE_INIT;
// Semaphore globally used to post events to the application thread
ICall_Semaphore sem;
// Entity ID globally used to check for source and/or destination of messages
ICall_EntityID selfEntityMain;
// Global pin resources
PIN_State pinGpioState;
PIN_Handle hGpioPin;
/*******************************************************************************
* LOCAL VARIABLES
*/
/*******************************************************************************
* TYPEDEFS
*/
// App event passed from profiles.
typedef struct
{
uint8_t event; // Which profile's event
uint8_t serviceID; // New status
uint8_t paramID;
} stEvt_t;
// Task configuration
static Task_Struct cadeiraTask;
static Char cadeiraTaskStack[ST_TASK_STACK_SIZE];
// Pins that are actively used by the application
static PIN_Config SensortagAppPinTable[] =
{
Board_LED1 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX, /* LED initially off */
Board_LED2 | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX, /* LED initially off */
Board_KEY_LEFT | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_BOTHEDGES | PIN_HYSTERESIS, /* Button is active low */
Board_KEY_RIGHT | PIN_INPUT_EN | PIN_PULLUP | PIN_IRQ_BOTHEDGES | PIN_HYSTERESIS, /* Button is active low */
Board_RELAY | PIN_INPUT_EN | PIN_PULLDOWN | PIN_IRQ_BOTHEDGES | PIN_HYSTERESIS, /* Relay is active high */
Board_BUZZER | PIN_GPIO_OUTPUT_EN | PIN_GPIO_LOW | PIN_PUSHPULL | PIN_DRVSTR_MAX, /* Buzzer initially off */
PIN_TERMINATE
};
void Cadeira_createTask(void)
{
Task_Params taskParams;
// Configure task
Task_Params_init(&taskParams);
taskParams.stack = cadeiraTaskStack;
taskParams.stackSize = ST_TASK_STACK_SIZE;
taskParams.priority = ST_TASK_PRIORITY;
Task_construct(&cadeiraTask, Cadeira_taskFxn, &taskParams, NULL);
}
/*******************************************************************************
* @fn SensorTag_taskFxn
*
* @brief Application task entry point for the SensorTag
*
* @param a0, a1 (not used)
*
* @return none
*/
static void Cadeira_taskFxn(UArg a0, UArg a1)
{
// Setup I2C for sensors
SensorI2C_open();
// Handling of buttons, LED, relay
hGpioPin = PIN_open(&pinGpioState, SensortagAppPinTable);
//PIN_registerIntCb(hGpioPin, SensorTag_callback);
// ***************************************************************************
// 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(&selfEntityMain, &sem);
// Create an RTOS queue for message from profile to be sent to app.
appMsgQueue = Util_constructQueue(&appMsg);
// Initialize application
SensorTagMov_init(); // Movement processor
// 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 signalled 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;
if (ICall_fetchServiceMsg(&src, &dest,
(void **)&pMsg) == ICALL_ERRNO_SUCCESS)
{
if ((src == ICALL_SERVICE_CLASS_BLE) && (dest == selfEntityMain))
{
// // Process inter-task message
// SensorTag_processStackMsg((ICall_Hdr *)pMsg);
}
if (pMsg)
{
ICall_freeMsg(pMsg);
}
}
// If RTOS queue is not empty, process app message.
while (!Queue_empty(appMsgQueue))
{
stEvt_t *pMsg = (stEvt_t *)Util_dequeueMsg(appMsgQueue);
if (pMsg)
{
// // Process message.
// SensorTag_processAppMsg(pMsg);
// Free the space from the message.
ICall_free(pMsg);
}
}
SensorTagMov_processSensorEvent();
}
}
}