[Sample SPI]ACT&INACT accelerometer's events ADXL345+FXT009


#1

Hardware

  • FXT009 + adapter for FXTE(50pin Expansion Card) to development
  • AnalogDevice ADXL345(datasheet) mounted on GY-29 board(pinout)

pin connection:
FXTE(50pin) <-> ADXL345
11 GSM 2V8 <-> Vcc
15 SPI1-CS /GPIO31 <-> CS
16 SPI1-CLK <-> SCLK
17 SPI1-I <-> SDO
18 SPI1-IO <-> SDI
29 GPIO19 <-> INT1
33 GPIO23 <-> INT2
49 GND <-> GND
picture 1
picture 2

OpenAT
I use adl_bus Library to comunicate with ADXL346(work also with I2C).
The function [i]ADXL345_gpioInt/i init three GPIO used and subscribe gpio event handler.

  • GPIO31 as output used as “manual CS”
  • GPIO19 and 23 as input to detect INT1&INT2 HIGH

After SPI bus initialized the [i]ADXL345_setup/i function set some registers to detect ACTIVITY and INACTIVITY events by interrupts

Code

  • adxl345_spi.h
/*
 * adxl345_spi.h
 *
 *  Created on: Jul 12, 2013
 *      Author: Miki Nacucchi
 */

#ifndef ADXL345_SPI_H_
#define ADXL345_SPI_H_

/* ------- Register names ------- */
#define ADXL345_DEVID 			0x00
#define ADXL345_RESERVED1		0x01
#define ADXL345_THRESH_TAP		0x1d
#define ADXL345_OFSX			0x1e
#define ADXL345_OFSY			0x1f
#define ADXL345_OFSZ			0x20
#define ADXL345_DUR				0x21
#define ADXL345_LATENT			0x22
#define ADXL345_WINDOW			0x23
#define ADXL345_THRESH_ACT		0x24
#define ADXL345_THRESH_INACT	0x25
#define ADXL345_TIME_INACT		0x26
#define ADXL345_ACT_INACT_CTL	0x27
#define ADXL345_THRESH_FF		0x28
#define ADXL345_TIME_FF			0x29
#define ADXL345_TAP_AXES		0x2a
#define ADXL345_ACT_TAP_STATUS	0x2b
#define ADXL345_BW_RATE			0x2c
#define ADXL345_POWER_CTL		0x2d
#define ADXL345_INT_ENABLE		0x2e
#define ADXL345_INT_MAP			0x2f
#define ADXL345_INT_SOURCE		0x30
#define ADXL345_DATA_FORMAT		0x31
#define ADXL345_DATAX0			0x32
#define ADXL345_DATAX1			0x33
#define ADXL345_DATAY0			0x34
#define ADXL345_DATAY1			0x35
#define ADXL345_DATAZ0			0x36
#define ADXL345_DATAZ1			0x37
#define ADXL345_FIFO_CTL		0x38
#define ADXL345_FIFO_STATUS		0x39


//ADXL345_DEVID default value
#define ADXL345_DEVID_VALUE		0xE5

/*
 Interrupt bit position in reg ADXL345_INT_ENABLE
 */
#define ADXL345_INT_DATA_READY_BIT 0x07
#define ADXL345_INT_SINGLE_TAP_BIT 0x06
#define ADXL345_INT_DOUBLE_TAP_BIT 0x05
#define ADXL345_INT_ACTIVITY_BIT   0x04
#define ADXL345_INT_INACTIVITY_BIT 0x03
#define ADXL345_INT_FREE_FALL_BIT  0x02
#define ADXL345_INT_WATERMARK_BIT  0x01
#define ADXL345_INT_OVERRUNY_BIT   0x00

/*
 Flag position in reg ADXL345_INT_SOURCE
 */
#define ADXL345_DATA_READY	0x07
#define ADXL345_SINGLE_TAP	0x06
#define ADXL345_DOUBLE_TAP	0x05
#define ADXL345_ACTIVITY	0x04
#define ADXL345_INACTIVITY	0x03
#define ADXL345_FREE_FALL	0x02
#define ADXL345_WATERMARK	0x01
#define ADXL345_OVERRUNY	0x00

#define ADXL345_ADDLENGTH	0x06

/*
 * GPIO def
 */
#define ADXL345_GPIO_COUNT	3

#define ADXL345_GPIO_CS		31
#define ADXL345_GPIO_INT1	19
#define ADXL345_GPIO_INT2	23

void ADXL345_setup();

void ADXL345_writeReg(u8 reg, u8 value);
void ADXL345_readReg(u8 reg, u8 length, void *buffer);

#endif /* ADXL345_SPI_H_ */
  • main.c
/*
 * main.c
 *
 *  Created on: Jul 12, 2013
 *      Author: Miki Nacucchi
 */
#include "adl_global.h"
#include "generated.h"

#include "adl_bus.h"
#include "adxl345_spi.h"

#include "adl_traces.h"
#define TRACE_LEVEL	5


adl_ioDefs_t gpioConfig[ADXL345_GPIO_COUNT] =
{
		ADL_IO_GPIO	|	ADXL345_GPIO_CS		| 	ADL_IO_DIR_OUT 	| 	ADL_IO_LEV_HIGH,	//CS
		ADL_IO_GPIO	|	ADXL345_GPIO_INT1	| 	ADL_IO_DIR_IN, 							//ADXL345_INT1
		ADL_IO_GPIO	|	ADXL345_GPIO_INT2	| 	ADL_IO_DIR_IN 							//ADXL345_INT2
};
s32 ADXL345_gpioHandle;

void ADXL345_gpioEventHandler( s32 GpioHandle, adl_ioEvent_e Event, u32 Size, void * Param ){
	//TRACE((TRACE_LEVEL,"ADXL345_gpioEventHandler"));

	if(Event != ADL_IO_EVENT_INPUT_CHANGED)
		return;

	bool readIntSource = false;

	unsigned int i=0;
	for(; i<Size ; i++){
		adl_ioDefs_t gpio = ((adl_ioDefs_t *)Param)[i];

		switch (gpio & ADL_IO_NUM_MSK) {

			case ADXL345_GPIO_INT1:
				if((gpio & ADL_IO_LEV_HIGH) > 0){
					TRACE((TRACE_LEVEL,"ADXL345_GPIO_INT1 | ADL_IO_LEV_HIGH"));
					readIntSource = true;
				}
				//else
				//	TRACE((TRACE_LEVEL,"ADXL345_GPIO_INT1 | ADL_IO_LEV_LOW"));
				break;

			case ADXL345_GPIO_INT2:
				if((gpio & ADL_IO_LEV_HIGH) > 0){
					TRACE((TRACE_LEVEL,"ADXL345_GPIO_INT2 | ADL_IO_LEV_HIGH"));
					readIntSource = true;
				}
				//else
				//	TRACE((TRACE_LEVEL,"ADXL345_GPIO_INT2 | ADL_IO_LEV_LOW"));
				break;

		}
	}

	if(readIntSource){
		char values[1];
		ADXL345_readReg(ADXL345_INT_SOURCE, 1, values);
		//TRACE((TRACE_LEVEL,"ADXL345_INT_SOURCE: %x", values[0]));
		//if(values[0] & (1 << ADXL345_DATA_READY))	TRACE((TRACE_LEVEL,"ADXL345_DATA_READY"));
		if(values[0] & (1 << ADXL345_SINGLE_TAP))	TRACE((TRACE_LEVEL,"ADXL345_SINGLE_TAP ADXL345_INT_SOURCE: %x", values[0]));
		if(values[0] & (1 << ADXL345_DOUBLE_TAP))	TRACE((TRACE_LEVEL,"ADXL345_DOUBLE_TAP ADXL345_INT_SOURCE: %x", values[0]));
		if(values[0] & (1 << ADXL345_ACTIVITY))		TRACE((TRACE_LEVEL,"ADXL345_ACTIVITY ADXL345_INT_SOURCE: %x", values[0]));
		if(values[0] & (1 << ADXL345_INACTIVITY))	TRACE((TRACE_LEVEL,"ADXL345_INACTIVITY ADXL345_INT_SOURCE: %x", values[0]));
		if(values[0] & (1 << ADXL345_FREE_FALL))	TRACE((TRACE_LEVEL,"ADXL345_FREE_FALL ADXL345_INT_SOURCE: %x", values[0]));
		//if(values[0] & (1 << ADXL345_WATERMARK))	TRACE((TRACE_LEVEL,"ADXL345_WATERMARK"));
		//if(values[0] & (1 << ADXL345_OVERRUNY))	TRACE((TRACE_LEVEL,"ADXL345_OVERRUNY"));
	}


}


void ADXL345_gpioInt(){

	s32 gpioEventSub = adl_ioEventSubscribe(ADXL345_gpioEventHandler);

	switch (gpioEventSub) {
		case ADL_RET_ERR_PARAM:
			TRACE((TRACE_LEVEL, "adl_ioEventSubscribe ERR ADL_RET_ERR_PARAM"));
			return;
		case ADL_RET_ERR_SERVICE_LOCKED:
			TRACE((TRACE_LEVEL, "adl_ioEventSubscribe ERR ADL_RET_ERR_SERVICE_LOCKED"));
			return;
		default:
			TRACE((TRACE_LEVEL, "adl_ioEventSubscribe OK"));
			break;
	}

	ADXL345_gpioHandle = adl_ioSubscribe (ADXL345_GPIO_COUNT, gpioConfig, ADL_TMR_TYPE_100MS, (u32)0x01, gpioEventSub);

	switch (ADXL345_gpioHandle) {
		case ADL_RET_ERR_PARAM:
			TRACE((TRACE_LEVEL, "adl_ioSubscribe ERR ADL_RET_ERR_PARAM"));
			break;
		case ADL_RET_ERR_DONE:
			TRACE((TRACE_LEVEL,"adl_ioSubscribe ERR ADL_RET_ERR_DONE"));
			break;
		case ADL_RET_ERR_NO_MORE_TIMERS:
			TRACE((TRACE_LEVEL,"adl_ioSubscribe ERR ADL_RET_ERR_NO_MORE_TIMERS"));
			break;
		case ADL_RET_ERR_NO_MORE_HANDLES:
			TRACE((TRACE_LEVEL,"adl_ioSubscribe ERR ADL_RET_ERR_NO_MORE_HANDLES"));
			break;
		case ADL_RET_ERR_SERVICE_LOCKED:
			TRACE((TRACE_LEVEL,"adl_ioSubscribe ERR ADL_RET_ERR_SERVICE_LOCKED"));
			break;
		default:
			TRACE((TRACE_LEVEL,"adl_ioSubscribe OK"));
			break;
	}
}

void ADXL345_CS_setLow() {
	gpioConfig[0] &= ~ADL_IO_LEV_HIGH;

	switch (adl_ioWrite(ADXL345_gpioHandle, ADXL345_GPIO_COUNT, gpioConfig)) {
		case OK://If one parameter has an incorrect value.
		//	 TRACE((TRACE_LEVEL,"adl_ioWrite  - OK"));
			break;
		case ADL_RET_ERR_PARAM:// if one parameter has an incorrect value.
			TRACE((TRACE_LEVEL,"adl_ioWrite  - ADL_RET_ERR_PARAM"));
			break;
		case ADL_RET_ERR_DONE://refers to the field #adl_ioError_e for more informations.  If the error information is #ADL_IO_GNOERR, the process has been completed with success for this GPIO.
			TRACE((TRACE_LEVEL,"adl_ioWrite  - ADL_RET_ERR_DONE"));
			break;
		case ADL_RET_ERR_UNKNOWN_HDL://if the handle is unknown
			TRACE((TRACE_LEVEL,"adl_ioWrite  - ADL_RET_ERR_UNKNOWN_HDL"));
	}
}
void ADXL345_CS_setHigh() {
	gpioConfig[0] += ADL_IO_LEV_HIGH;

	switch (adl_ioWrite(ADXL345_gpioHandle, ADXL345_GPIO_COUNT, gpioConfig)) {
		case OK://If one parameter has an incorrect value.
		//	 TRACE((TRACE_LEVEL,"adl_ioWrite  - OK"));
			break;
		case ADL_RET_ERR_PARAM:// if one parameter has an incorrect value.
			TRACE((TRACE_LEVEL,"adl_ioWrite  - ADL_RET_ERR_PARAM"));
			break;
		case ADL_RET_ERR_DONE://refers to the field #adl_ioError_e for more informations.  If the error information is #ADL_IO_GNOERR, the process has been completed with success for this GPIO.
			TRACE((TRACE_LEVEL,"adl_ioWrite  - ADL_RET_ERR_DONE"));
			break;
		case ADL_RET_ERR_UNKNOWN_HDL://if the handle is unknown
			TRACE((TRACE_LEVEL,"adl_ioWrite  - ADL_RET_ERR_UNKNOWN_HDL"));
	}
}





// SPI Subscription data [Customize for ADXL345]
const adl_busSPISettings_t ADXL345_SPIConfig = {
	2,  //ADXL max Clock = 5MHz => MaxFrequency / ( 1 + ClkSpeed ) = 13000 / (1 + 2) = 4300
	ADL_BUS_SPI_CLK_MODE_3, // Mode 3: rest state 1, data valid on falling edge
	ADL_BUS_SPI_ADDR_CS_NONE,//[not used]
	ADL_BUS_SPI_CS_POL_LOW, // Chip Select active in low state
	ADL_BUS_SPI_MSB_FIRST,
	ADL_IO_GPIO,			//[not used]
	ADL_BUS_SPI_LOAD_UNUSED,// LOAD signal [not used]
	ADL_BUS_SPI_DATA_UNIDIR,//3 wires mode (MISO, MOSI and CLK), two pins are used to handle separately input & output data signals
	ADL_BUS_SPI_MASTER_MODE,// Master mode
	ADL_BUS_SPI_BUSY_UNUSED //BUSY signal [not used]
};


// BUS Handles
s32 ADXL345_SPIHandle;

void MyFunction ( void ){
	TRACE((TRACE_LEVEL,"MyFunction"));

	ADXL345_gpioInt();


	// Subscribe to the SPI1 BUS
	ADXL345_SPIHandle = adl_busSubscribe ( ADL_BUS_ID_SPI, (u32)1, (void*)&ADXL345_SPIConfig );
	switch (ADXL345_SPIHandle) {
		case ADL_RET_ERR_PARAM://If one parameter has an incorrect value.
			 TRACE((TRACE_LEVEL,"adl_busSubscribe  - ADL_RET_ERR_PARAM"));
			break;
		case ADL_RET_ERR_BAD_HDL://If the bus is already open with this chip select or in a configuration uncompatible with this chip select.
			TRACE((TRACE_LEVEL,"adl_busSubscribe  - ADL_RET_ERR_BAD_HDL"));
			break;
		case ADL_RET_ERR_NOT_SUPPORTED://If a GPIO required by the provided bus configuration is currently subscribed by an Open AT<sup>®</sup> application.
			TRACE((TRACE_LEVEL,"adl_busSubscribe  - ADL_RET_ERR_NOT_SUPPORTED"));
			break;
		case ADL_RET_ERR_SERVICE_LOCKED://If the required bus type is not supported by the Wireless CPU on which the application is running.
			TRACE((TRACE_LEVEL,"adl_busSubscribe  - ADL_RET_ERR_SERVICE_LOCKED"));
			break;

		default://OK
			TRACE((TRACE_LEVEL,"adl_busSubscribe  - OK"));

			/**/u32 param = 8;
			switch (adl_busIOCtl ( ADXL345_SPIHandle, ADL_BUS_CMD_SET_ADD_SIZE, &param )) {
				case OK://On success
				 TRACE((TRACE_LEVEL,"adl_busIOCtl ADL_BUS_CMD_SET_ADD_SIZE - OK"));
				break;
				case ADL_RET_ERR_PARAM://If one parameter has an incorrect value.
				 TRACE((TRACE_LEVEL,"adl_busIOCtl ADL_BUS_CMD_SET_ADD_SIZE - ADL_RET_ERR_PARAM"));
				break;
				case ADL_RET_ERR_UNKNOWN_HDL://If the handle is unknown.
				 TRACE((TRACE_LEVEL,"adl_busIOCtl ADL_BUS_CMD_SET_ADD_SIZE - ADL_RET_ERR_UNKNOWN_HDL"));
				break;
				case ADL_RET_ERR_DONE:// If a error occurs during the operation.
				 TRACE((TRACE_LEVEL,"adl_busIOCtl ADL_BUS_CMD_SET_ADD_SIZE - ADL_RET_ERR_DONE"));
				break;
				case ADL_RET_ERR_BAD_HDL://If the required command is not usable for the current handle.
				 TRACE((TRACE_LEVEL,"adl_busIOCtl ADL_BUS_CMD_SET_ADD_SIZE - ADL_RET_ERR_BAD_HDL"));
				break;
				case ADL_RET_ERR_SERVICE_LOCKED://If the function was called from a low level interrupt handler (the function is forbidden in this context).
				 TRACE((TRACE_LEVEL,"adl_busIOCtl ADL_BUS_CMD_SET_ADD_SIZE - ADL_RET_ERR_SERVICE_LOCKED"));
				break;
				case ADL_RET_ERR_NOT_SUPPORTED://If the capabilities inform that no Asynchronous mode is possible
				 TRACE((TRACE_LEVEL,"adl_busIOCtl ADL_BUS_CMD_SET_ADD_SIZE - ADL_RET_ERR_NOT_SUPPORTED"));
				break;
			}
			switch (adl_busIOCtl ( ADXL345_SPIHandle, ADL_BUS_CMD_SET_DATA_SIZE , &param)) {
				case OK://On success
				 TRACE((TRACE_LEVEL,"adl_busIOCtl ADL_BUS_CMD_SET_DATA_SIZE - OK"));
				break;
				case ADL_RET_ERR_PARAM://If one parameter has an incorrect value.
				 TRACE((TRACE_LEVEL,"adl_busIOCtl ADL_BUS_CMD_SET_DATA_SIZE - ADL_RET_ERR_PARAM"));
				break;
				case ADL_RET_ERR_UNKNOWN_HDL://If the handle is unknown.
				 TRACE((TRACE_LEVEL,"adl_busIOCtl ADL_BUS_CMD_SET_DATA_SIZE - ADL_RET_ERR_UNKNOWN_HDL"));
				break;
				case ADL_RET_ERR_DONE:// If a error occurs during the operation.
				 TRACE((TRACE_LEVEL,"adl_busIOCtl ADL_BUS_CMD_SET_DATA_SIZE - ADL_RET_ERR_DONE"));
				break;
				case ADL_RET_ERR_BAD_HDL://If the required command is not usable for the current handle.
				 TRACE((TRACE_LEVEL,"adl_busIOCtl ADL_BUS_CMD_SET_DATA_SIZE - ADL_RET_ERR_BAD_HDL"));
				break;
				case ADL_RET_ERR_SERVICE_LOCKED://If the function was called from a low level interrupt handler (the function is forbidden in this context).
				 TRACE((TRACE_LEVEL,"adl_busIOCtl ADL_BUS_CMD_SET_DATA_SIZE - ADL_RET_ERR_SERVICE_LOCKED"));
				break;
				case ADL_RET_ERR_NOT_SUPPORTED://If the capabilities inform that no Asynchronous mode is possible
				 TRACE((TRACE_LEVEL,"adl_busIOCtl ADL_BUS_CMD_SET_DATA_SIZE - ADL_RET_ERR_NOT_SUPPORTED"));
				break;
			}

			ADXL345_setup();

			break;
	}


}

// Access configuration structure
adl_busAccess_t AccessConfig ={
		0, 0 // No Opcode, No Address
};
void ADXL345_writeReg(u8 reg, u8 value){
	ADXL345_CS_setLow();

	AccessConfig.Address = (u32)(reg << 24);//32bit required!
	//AccessConfig.Address = (u32)reg;

	u8 pDataToWrite[1] = { value };

	switch (adl_busWrite ( ADXL345_SPIHandle, &AccessConfig, 1, pDataToWrite )) {
		case OK://If one parameter has an incorrect value.
			 //TRACE((TRACE_LEVEL,"adl_busWrite  - OK"));
			break;
		case ERROR://If the bus is already open with this chip select or in a configuration uncompatible with this chip select.
			TRACE((TRACE_LEVEL,"adl_busWrite  - ERROR"));
			break;
		case ADL_RET_ERR_PARAM://If a GPIO required by the provided bus configuration is currently subscribed by an Open AT<sup>®</sup> application.
			TRACE((TRACE_LEVEL,"adl_busWrite  - ADL_RET_ERR_PARAM"));
			break;
		case ADL_RET_ERR_UNKNOWN_HDL://If a GPIO required by the provided bus configuration is currently subscribed by an Open AT<sup>®</sup> application.
			TRACE((TRACE_LEVEL,"adl_busWrite  - ADL_RET_ERR_UNKNOWN_HDL"));
			break;
		case ADL_RET_ERR_SERVICE_LOCKED://If the required bus type is not supported by the Wireless CPU on which the application is running.
			TRACE((TRACE_LEVEL,"adl_busWrite  - ADL_RET_ERR_SERVICE_LOCKED"));
	}

	AccessConfig.Address = 0;

	ADXL345_CS_setHigh();
}
void ADXL345_readReg(u8 reg, u8 length, void *buffer){
	ADXL345_CS_setLow();

	memset(buffer, length, 0x00);//flush buffer

	reg |= 0x80;//read mode
	AccessConfig.Address = (u32)(reg << 24);//32bit required!


 	switch (adl_busRead ( ADXL345_SPIHandle, &AccessConfig, length, buffer )) {
		case OK://If one parameter has an incorrect value.
			// TRACE((TRACE_LEVEL,"adl_busRead  - OK"));
			break;
		case ERROR://If the bus is already open with this chip select or in a configuration uncompatible with this chip select.
			TRACE((TRACE_LEVEL,"adl_busRead  - ERROR"));
			break;
		case ADL_RET_ERR_PARAM://If a GPIO required by the provided bus configuration is currently subscribed by an Open AT<sup>®</sup> application.
			TRACE((TRACE_LEVEL,"adl_busRead  - ADL_RET_ERR_PARAM"));
			break;
		case ADL_RET_ERR_UNKNOWN_HDL://If a GPIO required by the provided bus configuration is currently subscribed by an Open AT<sup>®</sup> application.
			TRACE((TRACE_LEVEL,"adl_busRead  - ADL_RET_ERR_UNKNOWN_HDL"));
			break;
		case ADL_RET_ERR_SERVICE_LOCKED://If the required bus type is not supported by the Wireless CPU on which the application is running.
			TRACE((TRACE_LEVEL,"adl_busRead  - ADL_RET_ERR_SERVICE_LOCKED"));
			break;
	}

 	AccessConfig.Address = 0;

 	ADXL345_CS_setHigh();
}


void ADXL345_setup(){
	TRACE((TRACE_LEVEL,"ADXL345_setup"));

	u8 values[1];

	ADXL345_readReg(ADXL345_DEVID, 1, values);
	if(values[0] != ADXL345_DEVID_VALUE)TRACE((TRACE_LEVEL,"ADXL345_DEVID: %x  /!\\ FAIL /!\\", values[0]));//maybe any hardware problems
	else TRACE((TRACE_LEVEL,"ADXL345_DEVID: %x", values[0]));//must be 0xE5 !

	//Put the ADXL345 into +/- 4G range by writing the value 0x01 to the DATA_FORMAT register.
	ADXL345_writeReg(ADXL345_DATA_FORMAT,	0x01);

	//Put the ADXL345 into Measurement Mode AutoSleep enabled
	ADXL345_writeReg(ADXL345_POWER_CTL,		0x18);

	/*		ACTIVITY & INCATIVITY	*/
	//Activity Threshold
	ADXL345_writeReg(ADXL345_THRESH_ACT,	0x4B);

	//Inactivity Threshold
	ADXL345_writeReg(ADXL345_THRESH_INACT,	0x25);
	//Inactivity Timeout
	ADXL345_writeReg(ADXL345_TIME_INACT,	0x0A);

	//Enable all axis
	ADXL345_writeReg(ADXL345_ACT_INACT_CTL,	0xFF);


	/*		INTERRUPT	*/
	//MAP INT1 ACTIVITY INT2 INACTIVITY(& OTHERS ENABLED)
	ADXL345_writeReg(ADXL345_INT_MAP,	~(1 << ADXL345_INT_ACTIVITY_BIT));


	//Enable Act e Inact
	ADXL345_writeReg(ADXL345_INT_ENABLE, (1 << ADXL345_INT_ACTIVITY_BIT) | (1 << ADXL345_INT_INACTIVITY_BIT));

	ADXL345_readReg(ADXL345_INT_SOURCE, 1, values);	//CLEAR INT_SOURCE
	TRACE((TRACE_LEVEL,"ADXL345_INT_SOURCE: %x", values[0]));
	if(values[0] & (1 << ADXL345_DATA_READY))	TRACE((TRACE_LEVEL,"ADXL345_DATA_READY"));
	if(values[0] & (1 << ADXL345_SINGLE_TAP))	TRACE((TRACE_LEVEL,"ADXL345_SINGLE_TAP"));
	if(values[0] & (1 << ADXL345_DOUBLE_TAP))	TRACE((TRACE_LEVEL,"ADXL345_DOUBLE_TAP"));
	if(values[0] & (1 << ADXL345_ACTIVITY))		TRACE((TRACE_LEVEL,"ADXL345_ACTIVITY"));
	if(values[0] & (1 << ADXL345_INACTIVITY))	TRACE((TRACE_LEVEL,"ADXL345_INACTIVITY"));
	if(values[0] & (1 << ADXL345_FREE_FALL))	TRACE((TRACE_LEVEL,"ADXL345_FREE_FALL"));
	if(values[0] & (1 << ADXL345_WATERMARK))	TRACE((TRACE_LEVEL,"ADXL345_WATERMARK"));
	if(values[0] & (1 << ADXL345_OVERRUNY))		TRACE((TRACE_LEVEL,"ADXL345_OVERRUNY"));/**/


}


void main_task(void) {
	TRACE((TRACE_LEVEL,"main_task"));
	MyFunction();
}

I hope that it’s all understandable and helpful.