AnsweredAssumed Answered

adxl362 driver application file

Question asked by deeksha.sharma on Apr 14, 2017
Latest reply on Apr 18, 2017 by DNechita
I'm currently using a driver application file for adxl362 provided by analog devices(.c file) . 
I have added a few things according to requirements of my PYNQ-Z1 board. I have added a communication between microblaze processor and the pmod since the peripheral is supposed to be interacting with it. 
The .bin file of this code is then being called by a python code being run on jupyter notebook. The pmod is working but it is always giving me an output of 65,65,65 no matter how much I move the device.
Kindly find my code below.
#include "ADXL362.h"
#include "pmod.h"

 

// MAILBOX_WRITE_CMD
#define READ_SINGLE_VALUE 0x3
#define READ_AND_LOG 0x7
// Log constants
#define LOG_BASE_ADDRESS (MAILBOX_DATA_PTR(4))
#define LOG_ITEM_SIZE sizeof(u32)
#define LOG_CAPACITY (4000/LOG_ITEM_SIZE)

 

 

/******************************************************************************/
/************************* Variables Declarations *****************************/
/******************************************************************************/
char selectedRange = 0;

 

/******************************************************************************/
/************************ Functions Definitions *******************************/
/******************************************************************************/

 

/***************************************************************************//**
* @brief Initializes communication with the device and checks if the part is
* present by reading the device id.
*
* @return 0 - the initialization was successful and the device is present;
* -1 - an error occurred.
*******************************************************************************/

 


char ADXL362_Init(void)

 

{
unsigned char regValue = 0;
char status = -1;

 


ADXL362_GetRegisterValue(&regValue, ADXL362_REG_PARTID, 1);
if((regValue != ADXL362_PART_ID))
{
status = -1;
}
selectedRange = 2; // Measurement Range: +/- 2g (reset default).

 

return status;
}

 

/***************************************************************************//**
* @brief Writes data into a register.
*
* @param registerValue - Data value to write.
* @param registerAddress - Address of the register.
* @param bytesNumber - Number of bytes. Accepted values: 0 - 1.
*
* @return None.
*******************************************************************************/
void ADXL362_SetRegisterValue(unsigned short registerValue,
unsigned char registerAddress,
unsigned char bytesNumber)
{
unsigned char buffer[4] = {0, 0, 0, 0};

 

buffer[0] = ADXL362_WRITE_REG;
buffer[1] = registerAddress;
buffer[2] = (registerValue & 0x00FF);
buffer[3] = (registerValue >> 8);
spi_transfer(SPI_BASEADDR, bytesNumber + 2, NULL, buffer);
}

 

/***************************************************************************//**
* @brief Performs a burst read of a specified number of registers.
*
* @param pReadData - The read values are stored in this buffer.
* @param registerAddress - The start address of the burst read.
* @param bytesNumber - Number of bytes to read.
*
* @return None.
*******************************************************************************/
void ADXL362_GetRegisterValue(unsigned char* pReadData,
unsigned char registerAddress,
unsigned char bytesNumber)
{
unsigned char buffer[32];
unsigned char index = 0;

buffer[0] = ADXL362_READ_REG;
buffer[1] = registerAddress;
for(index = 0; index < bytesNumber; index++)
{
buffer[index + 2] = pReadData[index];
}
spi_transfer(SPI_BASEADDR, bytesNumber + 2, pReadData, buffer);

}

 

/***************************************************************************//**
* @brief Reads multiple bytes from the device's FIFO buffer.
*
* @param pBuffer - Stores the read bytes.
* @param bytesNumber - Number of bytes to read.
*
* @return None.
*******************************************************************************/
void ADXL362_GetFifoValue(unsigned char* pBuffer, unsigned short bytesNumber)
{
unsigned char buffer[512];
unsigned short index = 0;

 

buffer[0] = ADXL362_WRITE_FIFO;
for(index = 0; index < bytesNumber; index++)
{
buffer[index + 1] = pBuffer[index];
}
spi_transfer(SPI_BASEADDR, bytesNumber + 2, pBuffer, buffer);

}

 

/***************************************************************************//**
* @brief Resets the device via SPI communication bus.
*
* @return None.
*******************************************************************************/
void ADXL362_SoftwareReset(void)
{
ADXL362_SetRegisterValue(ADXL362_RESET_KEY, ADXL362_REG_SOFT_RESET, 1);
}

 

/***************************************************************************//**
* @brief Places the device into standby/measure mode.
*
* @param pwrMode - Power mode.
* Example: 0 - standby mode.
* 1 - measure mode.
*
* @return None.
*******************************************************************************/
void ADXL362_SetPowerMode(unsigned char pwrMode)
{
unsigned char oldPowerCtl = 0;
unsigned char newPowerCtl = 0;

 

ADXL362_GetRegisterValue(&oldPowerCtl, ADXL362_REG_POWER_CTL, 1);
newPowerCtl = oldPowerCtl & ~ADXL362_POWER_CTL_MEASURE(0x3);
newPowerCtl = newPowerCtl |
(pwrMode * ADXL362_POWER_CTL_MEASURE(ADXL362_MEASURE_ON));
ADXL362_SetRegisterValue(newPowerCtl, ADXL362_REG_POWER_CTL, 1);
}

 

/***************************************************************************//**
* @brief Selects the measurement range.
*
* @param gRange - Range option.
* Example: ADXL362_RANGE_2G - +-2 g
* ADXL362_RANGE_4G - +-4 g
* ADXL362_RANGE_8G - +-8 g
*
* @return None.
*******************************************************************************/
void ADXL362_SetRange(unsigned char gRange)
{
unsigned char oldFilterCtl = 0;
unsigned char newFilterCtl = 0;

 

ADXL362_GetRegisterValue(&oldFilterCtl, ADXL362_REG_FILTER_CTL, 1);
newFilterCtl = oldFilterCtl & ~ADXL362_FILTER_CTL_RANGE(0x3);
newFilterCtl = newFilterCtl | ADXL362_FILTER_CTL_RANGE(gRange);
ADXL362_SetRegisterValue(newFilterCtl, ADXL362_REG_FILTER_CTL, 1);
selectedRange = (1 << gRange) * 2;
}

 

/***************************************************************************//**
* @brief Selects the Output Data Rate of the device.
*
* @param outRate - Output Data Rate option.
* Example: ADXL362_ODR_12_5_HZ - 12.5Hz
* ADXL362_ODR_25_HZ - 25Hz
* ADXL362_ODR_50_HZ - 50Hz
* ADXL362_ODR_100_HZ - 100Hz
* ADXL362_ODR_200_HZ - 200Hz
* ADXL362_ODR_400_HZ - 400Hz
*
* @return None.
*******************************************************************************/
void ADXL362_SetOutputRate(unsigned char outRate)
{
unsigned char oldFilterCtl = 0;
unsigned char newFilterCtl = 0;

 

ADXL362_GetRegisterValue(&oldFilterCtl, ADXL362_REG_FILTER_CTL, 1);
newFilterCtl = oldFilterCtl & ~ADXL362_FILTER_CTL_ODR(0x7);
newFilterCtl = newFilterCtl | ADXL362_FILTER_CTL_ODR(outRate);
ADXL362_SetRegisterValue(newFilterCtl, ADXL362_REG_FILTER_CTL, 1);
}

 

/***************************************************************************//**
* @brief Reads the 3-axis raw data from the accelerometer.
*
* @param x - Stores the X-axis data(as two's complement).
* @param y - Stores the Y-axis data(as two's complement).
* @param z - Stores the Z-axis data(as two's complement).
*
* @return None.
*******************************************************************************/
void ADXL362_GetXyz(short* x, short* y, short* z)
{
unsigned char xyzValues[6] = {0, 0, 0, 0, 0, 0};

 

ADXL362_GetRegisterValue(xyzValues, ADXL362_REG_XDATA_L, 6);
*x = ((short)xyzValues[1] << 8) + xyzValues[0];
*y = ((short)xyzValues[3] << 8) + xyzValues[2];
*z = ((short)xyzValues[5] << 8) + xyzValues[4];
}

 

/***************************************************************************//**
* @brief Reads the 3-axis raw data from the accelerometer and converts it to g.
*
* @param x - Stores the X-axis data.
* @param y - Stores the Y-axis data.
* @param z - Stores the Z-axis data.
*
* @return None.
*******************************************************************************/
void ADXL362_GetGxyz(float* x, float* y, float* z)
{
unsigned char xyzValues[6] = {0, 0, 0, 0, 0, 0};

 

ADXL362_GetRegisterValue(xyzValues, ADXL362_REG_XDATA_L, 6);
*x = ((short)xyzValues[1] << 8) + xyzValues[0];
*x /= (1000 / (selectedRange / 2));
*y = ((short)xyzValues[3] << 8) + xyzValues[2];
*y /= (1000 / (selectedRange / 2));
*z = ((short)xyzValues[5] << 8) + xyzValues[4];
*z /= (1000 / (selectedRange / 2));
}

 

/***************************************************************************//**
* @brief Reads the temperature of the device.
*
* @return tempCelsius - The value of the temperature(degrees Celsius).
*******************************************************************************/
float ADXL362_ReadTemperature(void)
{
unsigned char rawTempData[2] = {0, 0};
short signedTemp = 0;
float tempCelsius = 0;

 

ADXL362_GetRegisterValue(rawTempData, ADXL362_REG_TEMP_L, 2);
signedTemp = (short)(rawTempData[1] << 8) + rawTempData[0];
tempCelsius = (float)signedTemp * 0.065;

return tempCelsius;
}

 

/***************************************************************************//**
* @brief Configures the FIFO feature.
*
* @param mode - Mode selection.
* Example: ADXL362_FIFO_DISABLE - FIFO is disabled.
* ADXL362_FIFO_OLDEST_SAVED - Oldest saved mode.
* ADXL362_FIFO_STREAM - Stream mode.
* ADXL362_FIFO_TRIGGERED - Triggered mode.
* @param waterMarkLvl - Specifies the number of samples to store in the FIFO.
* @param enTempRead - Store Temperature Data to FIFO.
* Example: 1 - temperature data is stored in the FIFO
* together with x-, y- and x-axis data.
* 0 - temperature data is skipped.
*
* @return None.
*******************************************************************************/
void ADXL362_FifoSetup(unsigned char mode,
unsigned short waterMarkLvl,
unsigned char enTempRead)
{
unsigned char writeVal = 0;

 

writeVal = ADXL362_FIFO_CTL_FIFO_MODE(mode) |
(enTempRead * ADXL362_FIFO_CTL_FIFO_TEMP) |
ADXL362_FIFO_CTL_AH;
ADXL362_SetRegisterValue(writeVal, ADXL362_REG_FIFO_CTL, 1);
ADXL362_SetRegisterValue(waterMarkLvl, ADXL362_REG_FIFO_SAMPLES, 2);
}

 

/***************************************************************************//**
* @brief Configures activity detection.
*
* @param refOrAbs - Referenced/Absolute Activity Select.
* Example: 0 - absolute mode.
* 1 - referenced mode.
* @param threshold - 11-bit unsigned value that the adxl362 samples are
* compared to.
* @param time - 8-bit value written to the activity timer register. The
* amount of time (in seconds) is: time / ODR, where ODR - is
* the output data rate.
*
* @return None.
*******************************************************************************/
void ADXL362_SetupActivityDetection(unsigned char refOrAbs,
unsigned short threshold,
unsigned char time)
{
unsigned char oldActInactReg = 0;
unsigned char newActInactReg = 0;

 

/* Configure motion threshold and activity timer. */
ADXL362_SetRegisterValue((threshold & 0x7FF), ADXL362_REG_THRESH_ACT_L, 2);
ADXL362_SetRegisterValue(time, ADXL362_REG_TIME_ACT, 1);
/* Enable activity interrupt and select a referenced or absolute
configuration. */
ADXL362_GetRegisterValue(&oldActInactReg, ADXL362_REG_ACT_INACT_CTL, 1);
newActInactReg = oldActInactReg & ~ADXL362_ACT_INACT_CTL_ACT_REF;
newActInactReg |= ADXL362_ACT_INACT_CTL_ACT_EN |
(refOrAbs * ADXL362_ACT_INACT_CTL_ACT_REF);
ADXL362_SetRegisterValue(newActInactReg, ADXL362_REG_ACT_INACT_CTL, 1);
}

 

/***************************************************************************//**
* @brief Configures inactivity detection.
*
* @param refOrAbs - Referenced/Absolute Inactivity Select.
* Example: 0 - absolute mode.
* 1 - referenced mode.
* @param threshold - 11-bit unsigned value that the adxl362 samples are
* compared to.
* @param time - 16-bit value written to the inactivity timer register. The
* amount of time (in seconds) is: time / ODR, where ODR - is
* the output data rate.
*
* @return None.
*******************************************************************************/
void ADXL362_SetupInactivityDetection(unsigned char refOrAbs,
unsigned short threshold,
unsigned short time)
{
unsigned char oldActInactReg = 0;
unsigned char newActInactReg = 0;

/* Configure motion threshold and inactivity timer. */
ADXL362_SetRegisterValue((threshold & 0x7FF),
ADXL362_REG_THRESH_INACT_L,
2);
ADXL362_SetRegisterValue(time, ADXL362_REG_TIME_INACT_L, 2);
/* Enable inactivity interrupt and select a referenced or absolute
configuration. */
ADXL362_GetRegisterValue(&oldActInactReg, ADXL362_REG_ACT_INACT_CTL, 1);
newActInactReg = oldActInactReg & ~ADXL362_ACT_INACT_CTL_INACT_REF;
newActInactReg |= ADXL362_ACT_INACT_CTL_INACT_EN |
(refOrAbs * ADXL362_ACT_INACT_CTL_INACT_REF);
ADXL362_SetRegisterValue(newActInactReg, ADXL362_REG_ACT_INACT_CTL, 1);
}
int main(void)
{
int cmd;
//acl2_data;
u32 delay;
float x,y,z;
pmod_init(0,1);
config_pmod_switch(SS, MOSI, MISO, SPICLK,
GPIO_4, GPIO_5, GPIO_6, GPIO_7);

// to initialize the device
ADXL362_Init();

 

// Run application
while(1){

 

// wait and store valid command
while((MAILBOX_CMD_ADDR & 0x01)==0);
cmd = MAILBOX_CMD_ADDR;

switch(cmd){

case READ_SINGLE_VALUE:
// write out reading, reset mailbox
/*
MAILBOX_DATA(0) = GetGxyz;
MAILBOX_DATA(1) = GetGxyz;
MAILBOX_DATA(2) = GetGxyz;
MAILBOX_CMD_ADDR = 0x0;*/

 


ADXL362_GetGxyz(&x,&y,&z);
//ADXL362_ReadTemperature;
//MAILBOX_DATA(0) = tempCelsius;
MAILBOX_DATA(0) = x;
MAILBOX_DATA(1) = y;
MAILBOX_DATA(2) = z;
MAILBOX_CMD_ADDR = 0x0;
//Serial.println(x,y,z);
//return(x||y||z);

break;

 

//case READ_AND_LOG:
//#if 0 //Deeksha Commented to compile the code ************ Need to check
/*// initialize logging variables, reset cmd
cb_init(&pmod_log, LOG_BASE_ADDRESS, LOG_CAPACITY, LOG_ITEM_SIZE);
delay = MAILBOX_DATA(3);
MAILBOX_CMD_ADDR = 0x0;

 

do{
acl2_data = GetGxyz;
cb_push_back(&pmod_log, &acl2_data);
delay_ms(delay);

 

} while((MAILBOX_CMD_ADDR & 0x1)== 0);*/
//#endif
// break;

 

default:
// reset command
MAILBOX_CMD_ADDR = 0x0;
break;
}
}
return(0);

Outcomes