MMA955L pedometer issue in reading 6axis data

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

MMA955L pedometer issue in reading 6axis data

6,067 Views
prasannaprabhu7
Contributor III

I am using MMA955l pedometer sensor in STM32l4RTC MCU, which is connected to i2c and I need to read accelerometer data from chip. I did not find any sample source and going through datasheet and looking at examples I am following command sequence as :

   aTxBuffer[0] = 0x00;

  aTxBuffer[1] = 0x00;

  aTxBuffer[2] = 0x00;

  aTxBuffer[3] = 0x0C;

  MMA955L_AcclDataTx(aTxBuffer, 4); //Read ID command

 

//Read Pedometer ID

MMA955L_AcclDataRx(aRxBuffer, 16);

Note: I get response as :

0x00 0x80 0x0c 0x0c 0x7a 0xed 0x25 0x5d 0x01 0x01 0x02 0x02 0x01 0x06 0x03 0x41 when I read 16 bytes of data.

 

//command to request_to_start register configuration

aTxBuffer[0] = 0x01;

  aTxBuffer[1] = 0x10;

  aTxBuffer[2] = 0x00;

  aTxBuffer[3] = 0x04;

  MMA955L_AcclDataTx(aTxBuffer, 4);

aTxBuffer[0] = 0x01;

  aTxBuffer[1] = 0x20;

  aTxBuffer[2] = 0x00;

  aTxBuffer[3] = 0x04;

  aTxBuffer[4] = 0xAA;

  aTxBuffer[5] = 0xBB;

  aTxBuffer[6] = 0xCC;

  aTxBuffer[7] = 0xDD;

  HAL_Delay(100);

  MMA955L_AcclDataTx(aTxBuffer, 8);

 

//Interrupt_App_IDs register configuration

aTxBuffer[0] = 0x01;

aTxBuffer[1] = 0x20;

  aTxBuffer[2] = 0x0C ;

  aTxBuffer[3] = 0x04;

  aTxBuffer[4] = 0x06;

  aTxBuffer[5] = 0x00;

  aTxBuffer[6] = 0x00;

aTxBuffer[7] = 0x00;

  MMA955L_AcclDataTx(aTxBuffer, 8);

//Awake accelerometer

 

aTxBuffer[0] = 0x12;

  aTxBuffer[1] = 0x20;

  aTxBuffer[2] = 0x06;

  aTxBuffer[3] = 0x01;

  aTxBuffer[4] = 0x00;

MMA955L_AcclDataTx(aTxBuffer, 5);

 

//Put accel in legacy mode

aTxBuffer[0] = 0x18;

  aTxBuffer[1] = 0x20;

  aTxBuffer[2] = 0x00;

  aTxBuffer[3] = 0x01;

  aTxBuffer[4] = 0x10;

MMA955L_AcclDataTx(aTxBuffer, 5);

 

//Configure accelerometer xyz data

aTxBuffer[0] = 0x4;

  aTxBuffer[1] = 0x20;

  aTxBuffer[2] = 0x00;

  aTxBuffer[3] = 0xC;

  aTxBuffer[4] = 0x06;

  aTxBuffer[5] = 0x00;

  aTxBuffer[6] = 0x06;

  aTxBuffer[7] = 0x01;

  aTxBuffer[8] = 0x06;

  aTxBuffer[9] = 0x02;

  aTxBuffer[10] = 0x06;

  aTxBuffer[11] = 0x03;

  aTxBuffer[12] = 0x06;

  aTxBuffer[13] = 0x04;

  aTxBuffer[14] = 0x06;

aTxBuffer[15] = 0x05;

   MMA955L_AcclDataTx(aTxBuffer, 16);

//Reading aggregated data

aTxBuffer[0] = 0x12;

  aTxBuffer[1] = 0x20;

  aTxBuffer[2] = 0x06;

  aTxBuffer[3] = 0x01;

  aTxBuffer[4] = 0x00;

  MMA955L_AcclDataTx(aTxBuffer, 5);

 

//POst this read 6 bytes data

MMA955L_AcclDataRx(aRxBuffer, 6);

Note: Getting reply as 0x00 0x80 0x0c 0x0c 0x7a 0xed

 

Is that I am following proper steps or is that I need to change any ?

info : Here MMA955L_AcclDataTx is a function to transmit data to i2c slave and MMA955L_AcclDataRx is a function to receive i2c data from slave.

 

Regards,

Prasanna Prabhu

Labels (1)
16 Replies

4,219 Views
chiranjeevikinn
Contributor III

Hi,

I am working on pedometer( MMA9555L) which is interfaced with iMX6 processor.

I have the following questions:

1. Is the version information below correct?

2. How to configure MMA9555L for multiple applications ? For example I need both the directional data and pedometer data, is it possible to get both simultaneously?

Please share a sample code if you have.

Here is my application code.

txBuff[0] = 0x00;
txBuff[1] = 0x00;
txBuff[2] = 0x00;
txBuff[3] = 0x0C;

pedo_fd = open("/dev/i2c-2", O_RDWR)

pedo_ioc = ioctl(pedo_fd, I2C_SLAVE, 0x4C)

i2c_smbus_write_i2c_block_data(pedo_fd, 0X00, 0X04, txBuff);

i2c_smbus_read_i2c_block_data(pedo_fd, 0x00, rxBuff)

the output of read is as below:

0x0 0x80 0xc 0xc 0x5e 0xa3 0xa5 0x77 0x1 0x10x2 0x2 0x1 0x6 0x3 0x41

Thanks,

Chiru

0 Kudos

4,219 Views
JackITB
NXP Employee
NXP Employee

Hi Satish,

Yes, the MMA9555 is operating at a supply voltage of 1.8V +/-5%. This is also the nominal voltage for all digital I/O pins so please align your board supply tree accordingly.

Keep in mind that the level of pin8 (RGPIO3) during reset determines which slave interface mode will be used by the device (set pin to high level for I2C mode).

At last, can you be more specific regarding "MMA not detecting" ? What command message do you send, what answer do you get if any... Any digital Scope plot of the I2C lines would help.

Regards,     Jacques.

0 Kudos

4,219 Views
JackITB
NXP Employee
NXP Employee

Hi Satish,

My apologies for the delayed response.

You may have in mind a more sophisticated communication Interface that what's proposed by MMA9555.

The Mailboxes can be considered simply as fixed address registers, just like any sensor device. Main difference is that their content depends on the Application ID that is invoked (unless "legacy mode" is used).

Finally as I have hard time to understand what kind of information your are missing, I put a brief guide for the Mailbox operation in the document attached.

I hope it will help, let me know otherwise.

Regards,     Jacques.

0 Kudos

4,225 Views
JackITB
NXP Employee
NXP Employee

Hi Satish,

I'm afraid, we can only provide FW support for our NXP MCU.

Nevertheless here are a few comments:

1/  0x4C is the MMA9555 "7-bits" I2C slave address, this means that the R/W flag (LSB bit) is not included !

To get the "8-bits" address (which may be what the I2C driver is expected ?) you need to do a "1 bit left shift" and add R/W flag. So full 8-bits I2C Write address is twice this value = 0x98 (whereas Read address is 0x99)

2/ Pedometer Application Identifier (i.e. 0x15) is not a "sub-address", this is the value/data you need to write in MMA9555 mailbox address 0. Actually the "sub-address" is 0x00 for most of the Write & Read transactions. Again see MMA9555 documentation provided.

3/ if you still struggle, send me plots of the I2C signals during the Write/Read transactions

Regards,     Jacques.

0 Kudos

4,225 Views
satishchauhan
Contributor II

Thank you Jaques for your quick response.

On Tue, Apr 12, 2016 at 12:06 AM, JackITB <admin@community.freescale.com>

0 Kudos

4,225 Views
satishchauhan
Contributor II

Hello Jaques,

I am working on pedometer (mma9555l).. Pedometer is not detecting in my board. I have tested the same board with arduno uno i2c scanner & with i2c poll function.. then also it not detecting mma.. same i2c code is working fr other slaves(max,Tmp).. I have gone through the data sheet of mma.. They have mentioned SCA SDA should be =1.8 v..
But in my board it showing 2.27V..
Is this reason for not detecting mma..?

Again i have tried with 1.8 v..den also mma is not detecting. How I should confirm that Mma9555l is working or not in my board . Please some one help how to solve this problem.

Regards

Satish

0 Kudos

4,224 Views
satishchauhan
Contributor II

Hello JackITB,

Thank you Jaques for your reply. I am working on PIC24fj64ga004 MCU, Here i

am communicating with 3 slaves (MAX30100,MMA9555L & OLED) by i2c

communication. while communicating with slaves am passing device

address(slave address) to following functions (ie : int I2C1_M_Poll(0X4C)

then it is not reading data it is directly coming out of loop. If i pass

slave address of (MAX30100(ie =0XAE)) code is working, but i pass device

address for MMA9555L (ie= 0X4C)then it is not detecting anything. my

question is why this device address (ox4c) is not detecting what is my

mistake i code. please tell the proper way to write it.

As you mentioned in data sheet like (MMA9555l device address is 0x4c

and Pedometer Application Identifier is 0x15 this am considering

as sub-address ) and these parameters am passing in my I2c communication

what parameters i need to pass in these function so it work properly as am

passing

I2C1_M_Poll(unsigned int DevAddr); EX: (I2C1_M_Poll(0X4C);)

I2C1_M_Read(unsigned int DevAddr,unsigned int SubAddr, int ByteCnt, char

*buffer); EX: ( I2C1_M_Read(0X4D,0X15,1,bufffer))

I2C1_M_ReadByte(unsigned int);

I2C1_M_Write(0X4C,0X15,1,bufffer);

I2C1_M_WriteByte('a');

This is first time i am implimenting this i2c communication .Here

somewhere am doing wrong please explain steps what should i do after this

i2c communication.Hope this time you replay quickly.

#include <p24FJ64GA004.h>

#include "i2c.h"

#include "delay.h"

//Variables//

unsigned int I2Cflags;

//Function prototype;

void I2C_HWini(void);

void I2C_ModuleStart(void);

void I2C_SWini(void);

int I2C1_M_BusReset(void);

void I2C1_M_ClearErrors(void);

int I2C1_M_Poll(unsigned int);

int I2C1_M_Read(unsigned int, unsigned int, int, char *);

int I2C1_M_ReadByte(unsigned int);

int I2C1_M_RecoverBus(void);

int I2C1_M_Restart(void);

int I2C1_M_Start(void);

int I2C1_M_Stop(void);

int I2C1_M_Write(unsigned int,unsigned int, int, char *);

int I2C1_M_WriteByte(char);

//int MMMA9555L_data_Tx(char*,int);

void I2C_HWini() //Set pin drive modes //I2C - drive outputs so we can

manually clear lines

{

LATBbits.LATB8 = 1;

LATBbits.LATB9 = 1; //Start with bus in idle mode - both lines hig

ODCBbits.ODB2 = 1; //Open drain mode

ODCBbits.ODB3 = 1;

// TRISBbits.TRISB8 = 0; //SCL1 output

// TRISBbits.TRISB9 = 0; //SDA1

output

}

void I2C_ModuleStart()

{

OSCCON = 0X2200;

// OSCTUN = 0X0000;

CLKDIV = 0X0000;

I2C1CON = 0x1000; //Set all bits to known state

I2C1CONbits.I2CEN = 0; //Disable until everything set up. Pins will be std

IO.

I2C1BRG = 39; //I2C1BRG = (Fcy/Fscl-FCY/10E6)

I2C1CONbits.DISSLW = 0; //Enable slew rate control for 400kHz operation

IFS1bits.MI2C1IF = 0; //Clear I2C master int flag

I2C1CONbits.I2CEN = 1; //Enable I2C //For interrupt driven code

IEC1bits.MI2C1IE = 1; //Enable I2C master interrupt

}

void I2C_SWini()

{

unsigned int I2Cflags = 0;

SetI2C1BusDirty; //I2C bus in unknown state, go ahead and clear it

}

int I2C1_M_BusReset()

{

int i;

//Start with lines high - sets SCL high if not already there

LATBbits.LATB8 = 1; //PORTBbits.RG2 = 1 is equivalent

LATBbits.LATB9 = 1;

delay(1); //Need 5uS delay

if(PORTBbits.RB2 == 0) //Read if line actually went high

{

return I2C_Err_SCL_low; //SCL stuck low - is the pullup resistor loaded?

}

i=10; //SCL ok, toggle until SDA goes high.

while(i>0)

{

if(PORTBbits.RB3 == 1) //If SDA is high, then we are done

{

break;

}

LATBbits.LATB8 = 0; //SCL low

delay(1); //Need 5uS delay

LATBbits.LATB8 = 1; //SCL high

delay(1); //Need 5uS delay

i--;

}

if((PORTB & 0x000C) != 0x000C) //We are ok if SCL and SDA high

{

return I2C_Err_SDA_low;

}

LATBbits.LATB9 = 0; //SDA LOW while SCL HIGH -> START

delay(1); //Need 5uS delay

LATBbits.LATB9 = 1; //SDA HIGH while SCL HIGH -> STOP

delay(1); //Need 5uS delay

return I2C_OK;

}

void I2C1_M_ClearErrors()

{

I2C1CONbits.RCEN = 0; //Cancel receive request

I2C1STATbits.IWCOL = 0; //Clear write-collision flag

I2C1STATbits.BCL = 0; //Clear bus-collision flag

}

int I2C1_M_Poll(unsigned int DevAddr)

{

int retval;

int SlaveAddr;

SlaveAddr = (DevAddr << 1) | 0;

if(IsI2C1BusDirty)

{

I2C1_M_ClearErrors();

if(I2C1_M_RecoverBus()==I2C_OK)

{//Recovered

ClrI2C1BusDirty;

}

else

{

return I2C_Err_Hardware;

}

}

if(I2C1_M_Start() == I2C_OK)

{

retval = I2C1_M_WriteByte((char)SlaveAddr);

if(I2C1_M_Stop() == I2C_OK) //Even if we have an error sending, try to

close I2C

{

if(retval == I2C_ACK)

{

return I2C_OK;

}

else if(retval == I2C_Err_NAK)

{

return I2C_Err_BadAddr; //Check that correct device address is being used

}

else

{

return I2C_Err_CommFail;

}

}

}

//Get here then we had an error

SetI2C1BusDirty; //Set error flag

return I2C_Err_CommFail;

}

int I2C1_M_Read(unsigned int DevAddr,unsigned int SubAddr, int ByteCnt,

char *buffer)

{

int SlaveAddr;

int retval;

int i;

if(IsI2C1BusDirty) //Ignore requests until Poll cmd is called to fix err.

return I2C_Err_BusDirty;

if(I2C1_M_Start() != I2C_OK) //Start

{//Failed to open bus

SetI2C1BusDirty;

return I2C_Err_CommFail;

}

SlaveAddr = (DevAddr << 1) | 0; //Device Address + Write bit

retval = I2C1_M_WriteByte((char)SlaveAddr);

if(retval == I2C_Err_NAK)

{

//Bad Slave Address or I2C slave device stopped responding

I2C1_M_Stop();

SetI2C1BusDirty; //Will reset slave device

return I2C_Err_BadAddr;

}

else if(retval<0)

{

I2C1_M_Stop();

SetI2C1BusDirty;

return I2C_Err_CommFail;

}

if( I2C1_M_WriteByte((char)SubAddr) != I2C_OK) //Sub Addr

{

I2C1_M_Stop();

SetI2C1BusDirty;

return I2C_Err_CommFail;

}

if( I2C1_M_Restart() != I2C_OK) //Repeated start - switch to read mode

{

I2C1_M_Stop();

SetI2C1BusDirty;

return I2C_Err_CommFail;

}

SlaveAddr = (DevAddr << 1) | 0x01; //Device Address + Read bit

if( I2C1_M_WriteByte((char)SlaveAddr) != I2C_OK) //Slave Addr

{

I2C1_M_Stop();

SetI2C1BusDirty;

return I2C_Err_CommFail;

}

for(i=0;i<ByteCnt;i++) //Data

{

if(i==(ByteCnt-1) )

{

retval = I2C1_M_ReadByte(I2C_M_NACK); //NACK on last byte so slave knows

this is it

}

else

{

retval = I2C1_M_ReadByte(I2C_M_ACK);

}

if(retval >= 0)

{

buffer[i] = retval;

}

else

{

//Error while reading byte. Close connection and set error

flag.

I2C1_M_Stop();

SetI2C1BusDirty;

return I2C_Err_CommFail;

}

}

if(I2C1_M_Stop() != I2C_OK)

{//Failed to close bus

SetI2C1BusDirty;

return I2C_Err_CommFail;

}

return I2C_OK; //Success

}

int I2C1_M_ReadByte(unsigned int ACKflag)

{

int t;

if(ACKflag == I2C_M_NACK) //Set state in preparation for TX below

{

I2C1CONbits.ACKDT = 1;//NACK

}

else

{

I2C1CONbits.ACKDT = 0;//ACK

}

I2C1CONbits.RCEN = 1; //Start receive

t=0;//Timeout is processor speed dependent. @(4*8Mhz=16MIPS) and 8 bits, I

expect <=320.

//We could wait for RCEN to be cleared, but are really interested in

incoming byte, so look for I2C1STAT.RBF

while(!I2C1STATbits.RBF) //HW cleared when receive complete

{

t++;

if(t>8000)

{ //SCL stuck low

//RCEN cannot be cleared in SW. Will need to reset I2C interface, or wait

until SCL goes high.

return I2C_Err_RcvTimeout;

}

} //Tested: t=30

//I2C1STATbits.RBF will likely be set

//As the master we must ACK or NACK every byte, so slave knows if it

will send another byte.

//We have set the bit above, just need to send it

I2C1CONbits.ACKEN = 1; //Send ACK bit now

t=0; //Timeout is processor speed dependent.

@(4*8Mhz=16MIPS), I expect <=40.

while(I2C1CONbits.ACKEN) //HW cleared when complete

{

t++;

if(t>1000)

{//This will timeout if SCL stuck low

//ACKEN cannot be cleared in SW. I2C interface must be reset after this

error.

return I2C_Err_SCL_low;

}

}//Tested: t=4

if(I2C1STATbits.I2COV) //If an overflow occurred, it means we received a

new byte before reading last one

{

I2C1STATbits.I2COV = 0;

return I2C_Err_Overflow;

}

return I2C1RCV; //Reading this register clears RBF

}

int I2C1_M_RecoverBus()

{

int status;

I2C1CONbits.I2CEN = 0;

status = I2C1_M_BusReset();

if(status>0)

{//Fatal I2C error, nothing we can do about it

return I2C_Err_Hardware;

}

//That worked, bring I2C back online

I2C1CONbits.I2CEN = 1;

return I2C_OK;

}

int I2C1_M_Restart()

{

int t;

I2C1CONbits.RSEN = 1; //Initiate restart condition

t=0;

while(I2C1CONbits.RSEN) //HW cleared when complete

{

t++;

if(t>1000)

{

return I2C_Err_SCL_low;

}

}//Tested: t=5

if(I2C1STATbits.BCL)

{//SDA stuck low

I2C1STATbits.BCL = 0; //Clear error to regain control of I2C

return I2C_Err_BCL;

}

return I2C_OK;

}

int I2C1_M_Start()

{

int t;

I2C1CONbits.SEN = 1; //Initiate Start condition

Nop();

if(I2C1STATbits.BCL)

{//SCL or SDA stuck low

I2C1CONbits.SEN = 0; //Cancel request (will still be set if we had previous

BCL)

I2C1STATbits.BCL = 0; //Clear error to regain control of I2C

return I2C_Err_BCL;

}

if(I2C1STATbits.IWCOL)

{//Not sure how this happens but it occurred once, so trap here

I2C1CONbits.SEN = 0; //Clear just in case set

I2C1STATbits.IWCOL = 0; //Clear error

return I2C_Err_IWCOL;

}

t=0;

while(I2C1CONbits.SEN) //HW cleared when complete

{

t++;

if(t>1000)

{//Since SCL and SDA errors are trapped by BCL error above, this should

never happen

return I2C_Err_TimeoutHW;

}

}

if(I2C1STATbits.BCL)

{

I2C1STATbits.BCL = 0; //Clear error to regain control of I2C

return I2C_Err_BCL;

}

return I2C_OK;

}

int I2C1_M_Stop()

{

int t;

I2C1CONbits.PEN = 1; //Initiate stop condition

Nop();

if(I2C1STATbits.BCL)

{//Not sure if this can ever happen here

I2C1STATbits.BCL = 0; //Clear error

return I2C_Err_BCL; //Will need to reset I2C interface.

}

t=0;//Timeout is processor speed dependent. @(4*8Mhz=16MIPS), I expect

<=40.

while(I2C1CONbits.PEN) //HW cleared when complete

{

t++;

if(t>1000)

{//Will timeout if SCL stuck low

//PEN cannot be cleared in SW. Will need to reset I2C interface.

return I2C_Err_SCL_low;

}

}//Tested: t=5

return I2C_OK;

}

int I2C1_M_Write(unsigned int DevAddr,unsigned int SubAddr, int

ByteCnt, char *buffer)

{

int i;

int retval;

unsigned int SlaveAddr;

if(IsI2C1BusDirty) //Ignore requests until Poll cmd is called to fix err.

return I2C_Err_BusDirty;

if(I2C1_M_Start() != 0) //Start

{//Failed to open bus

SetI2C1BusDirty;

return I2C_Err_CommFail;

}

SlaveAddr = (DevAddr << 1) | 0; //Device Address + Write bit

retval = I2C1_M_WriteByte((char)SlaveAddr);

if(retval == I2C_Err_NAK)

{//Bad Slave Address or I2C slave device stopped responding

I2C1_M_Stop();

SetI2C1BusDirty; //Will reset slave device

return I2C_Err_BadAddr;

}

else if(retval<0)

{

I2C1_M_Stop();

SetI2C1BusDirty;

return I2C_Err_CommFail;

}

if( I2C1_M_WriteByte((char)SubAddr) != I2C_ACK) //Sub Addr

{

I2C1_M_Stop();

SetI2C1BusDirty;

return I2C_Err_CommFail;

}

for(i=0;i<ByteCnt;i++) //Data

{

if( I2C1_M_WriteByte(buffer[i]) != I2C_ACK)

{//Error while writing byte. Close connection and set error flag.

I2C1_M_Stop();

SetI2C1BusDirty;

return I2C_Err_CommFail;

}

}

if(I2C1_M_Stop() != I2C_OK)

{//Failed to close bus

SetI2C1BusDirty;

return I2C_Err_CommFail;

}

return I2C_OK;

}

int I2C1_M_WriteByte(char cData)

{

int t;

if(I2C1STATbits.TBF) //Is there already a byte waiting to send? //TBF

Transmission Buffer full

{

return I2C_Err_TBF;

}

I2C1TRN = cData; //Send byte

t=0;

while(I2C1STATbits.TRSTAT) //HW cleared when TX complete

{

t++;

if(t>8000)

{//This is bad because TRSTAT will still be set

return I2C_Err_SCL_low; //Must reset I2C interface, and possibly slave

devices

}

}//Testing: t=31

if(I2C1STATbits.BCL)

{

I2C1STATbits.BCL = 0; //Clear error to regain control of I2C

return I2C_Err_BCL;

}

//Done, now how did slave respond?

if(I2C1STATbits.ACKSTAT) //1=NACK

return I2C_Err_NAK; // NACK

else

return I2C_ACK; // ACK

}

Thanks & Regards

satish

On Fri, Apr 8, 2016 at 8:01 PM, JackITB <admin@community.freescale.com>

0 Kudos

4,224 Views
JackITB
NXP Employee
NXP Employee

Hi Satish,

We usually don't provide sample code for MCUs not pertaining to NXP portfolio.

You should get some generic I2C driver code for the PIC MCU, then we can help you configure and operate MMA9555L (slave I2C address = 0x4C) according to your need.

All what it takes is to send some commands (writing consecutive bytes) and getting answers (reading consecutive bytes).

If you share your targeted settings, we'll provide the query/response command list.

Regards,     Jacques.

4,224 Views
satishchauhan
Contributor II

Hi Jacques Trichet

Thank you for your reply. I have  code for PIC MCU i2c driver, I have gone trough the data sheet of MMA955l pedometer In that they have given some configuration of mailbox implementation. My question is how to configure the mail box?. HOw it work it works? is it work like what we use in Linux (IPC mechanism) for synchronization or what?. if you have any source code for that mailbox configuration then please post here.

Thanks & Regards

satish Chauhan


0 Kudos

4,224 Views
satishchauhan
Contributor II

Hi All,

I am working on PIC24FJ64GA004 MCU and on MMA9555L connected to IIC. Is there any sample source code available for the same ?

0 Kudos

4,220 Views
JackITB
NXP Employee
NXP Employee

Hi Prasanna,

Actually I would recommend that you add a ~50ms delay after each command sent to MMA9555L. This will make sure that the sensor has enough time to execute the command prior receiving the next one.

Alternatively, you can set INT_O output line to toggle when command has been completed: W00 18 20 00 01 90

Regards,    Jacques.

PS: you'll find attached the communication log I have with my set-up

0 Kudos

4,220 Views
JackITB
NXP Employee
NXP Employee

This is weird.

Could you add a tempo (i.e. "wait 50ms") inside the while(1) loop, so that the reading is not overwhelming the slave interface.

If you still are not successful, best is to send us the slave port traffic log (time stamp, byte stream) for us to analyze.

0 Kudos

4,220 Views
prasannaprabhu7
Contributor III

Thank you Jaques for your reply. Is did send above commands but I did not receive accelerometer data changing on changing axes and instead all time same data is read as  0x04 0x80 0x0c 0x0c 0x06 0x00 0x06 0x02 0x06 0x04. Any suggestions ?

regards,

Prasanna

0 Kudos

4,220 Views
JackITB
NXP Employee
NXP Employee

Hi Prasanna,

Let me try to analyze your configuration. I will use following convention (all in hexadecimal):

Wnn xx yy etc... to indicate a continuous write transaction starting at address nn, of bytes xx yy etc...

and Rnn xx yy etc... to indicate a continuous read transaction starting at address nn, yielding bytes xx yy etc...

Below are your sequence of commands and my associated comments.

1/ W00 00 00 00 0C                              => ok

2/ R00 00 80 0C 0C 7A etc...               => ok

3/ W00 01 10 00 04                               => query configuration bytes 00 to 04 (Request_to_start registers) of the Scheduler Application (cf "command/response" communication scheme)

If you read those registers: R00 01 80 04 04 00 00 00 00     they should be all at 00

4/ W00 01 20 00 04 AA BB CC DD      => update configuration bytes 00 to 04 (Request_to_start registers) of the Scheduler Application

This command (from MMA9555L datasheet) is simply a dummy example so meaningless in your case.

5/ W00 01 20 0C 04 06 00 00 00          =>  write configuration bytes 0C to 0F (IRQ_Interrupt_AppIDs) of the Scheduler Application

This assigns IRQ interrupt to AppID 0x19 and 0x1A ( 06 00 00 00 <=> bits n° 25 & 26)

I don't think you need to change anything in the scheduler application settings so previous 3 commands are not necessary. And actually commands 4 & 5 are not relevant

6/ W00 12 20 06 01 00                         => ok

7/ W00 18 20 00 01 10                         => ok

8/ W00 04 20 00 0C 06 00 etc..           => ok

9/ W00 12 20 06 01 00                         => redundant as already done by command 6/

10/ R00 00 08 0C 0C 7A ED => looks like the same as version application answer so something wrong in your sequence

Moreover, as you have configured the mailbox to "quickread" the AFE XYZ output data, you should directly read mailboxes 04 to 09

Doing so: R04 00 05 FF 9D 10 58      => I got X=0005, Y=FF9D, Z=1058 (demoboard in horizontal position)

So at least it's working fine at my side.

As a general recommendation (at least for troubleshooting), it may be worthwhile to check that command has completed successfully by reading first 4 mailboxes: 1st byte = AppID code, 2nd = COCO flag + error code if any (should be 80), 3rd = actual number of bytes read/written, 4th = requested number of bytes read/written

I suggest you implement the changes I mentioned, then let me know if you still face issues.

In that case, what can help is to log the I2C traffic between your Host MCU and MMA9555L.

Regards,      Jacques.

0 Kudos

4,220 Views
prasannaprabhu7
Contributor III

Thank you Jacques for your kind response. As per your suggestions I did modify my application. These are the commands I am sending.

aTxBuffer[0] = 0x00;

  aTxBuffer[1] = 0x00;

  aTxBuffer[2] = 0x00;

  aTxBuffer[3] = 0x0C;

  MMA955L_AcclDataTx(aTxBuffer, 4); //Read ID command

//On Reading response

MMA955L_AcclDataRx(aRxBuffer, 16);

//Response buffer data:

0x00 0x80 0x0c 0x0c 0x7a 0xed 0x25 0x5d 0x01 0x01 0x02 0x02 0x01 0x06 0x03 0x41

//command to request_to_start register configuration

aTxBuffer[0] = 0x00;

  aTxBuffer[1] = 0x01;

  aTxBuffer[2] = 0x10;

  aTxBuffer[3] = 0x00;

  aTxBuffer[4] = 0x04;

  MMA955L_AcclDataTx(aTxBuffer, 5);

//Read Response :

MMA955L_AcclDataRx(aRxBuffer, 8);

//Response data is on reading is 01 80 04 04 00 00 00 00

//Put module to awake if it was in sleep

  aTxBuffer[0] = 0x00;

  aTxBuffer[1] = 0x12;

  aTxBuffer[2] = 0x20;

  aTxBuffer[3] = 0x06;

  aTxBuffer[4] = 0x01;

  aTxBuffer[5] = 0x00;

  MMA955L_AcclDataTx(aTxBuffer, 6);

//Put device in legacy mode

aTxBuffer[0] = 0x00;

  aTxBuffer[1] = 0x18;

  aTxBuffer[2] = 0x20;

  aTxBuffer[3] = 0x00;

  aTxBuffer[4] = 0x01;

  aTxBuffer[5] = 0x10;

    MMA955L_AcclDataTx(aRxBuffer, 6);

//Configure accelerometer

  aTxBuffer[0] = 0x00;

  aTxBuffer[1] = 0x04;

  aTxBuffer[2] = 0x20;

  aTxBuffer[3] = 0x00;

  aTxBuffer[4] = 0x0c;

  aTxBuffer[5] = 0x06;

  aTxBuffer[6] = 0x00;

  aTxBuffer[7] = 0x06;

  aTxBuffer[8] = 0x01;

  aTxBuffer[9] = 0x06;

  aTxBuffer[10] = 0x02;

  aTxBuffer[11] = 0x06;

  aTxBuffer[12] = 0x03;

  aTxBuffer[13] = 0x06;

  aTxBuffer[14] = 0x04;

  aTxBuffer[15] = 0x06;

  aTxBuffer[16] = 0x05;

   MMA955L_AcclDataTx(aTxBuffer, 17);

//read data continuosly

while(1)

{

MMA955L_AcclDataRx(aRxBuffer, 10);

}

//Response is 0x04 0x80 0x0c 0x0c 0x06 0x00 0x06 0x01 0x06 0x02 this looks like configure mailbox command is copied back toRX registers

//This data is always constant even if position of board is changed.

1> Should we configure any scheduler/ Analog Front End to get Accelerometer data (X,Y,Z) ??

2>Can you Provide us the sample code on which you got accelerometer axes data continuously getting updated on changing board position?

( I did probe the data lines and the data I am receiving is properly copied to buffer with proper clock cycles matching with the ones given in datasheet.)

Regards,

Prasanna

                         

0 Kudos

4,220 Views
JackITB
NXP Employee
NXP Employee

Hi Prasanna,

I'm afraid you got confused by my previous answer so let me clarify it, especially the convention I've used:

Wnn xx yy etc... to indicate a continuous write transaction starting at address nn, of bytes xx yy etc... (all in hexadecimal)

and Rnn xx yy etc... to indicate a continuous read transaction starting at address nn, yielding bytes xx yy etc...

So the command W00 12 20 06 01 00 reflects a write transaction starting at address 00 (which is Mailbox 0) of following 5 bytes

MB0 = 12

MB1 = 20

MB2 = 06

MB3 = 01

MB4 = 00

This means you should not embed "W00" in your TxBuffer (aTxBuffer[0] = 0x00) as it is simply the destination (mailbox/register address) of the first byte.

Similarly R04 00 05 FF 9D 10 58 reflects a Read transaction starting at address 04 (Mailbox 4) of 6 consecutive bytes

MB4 = 00

MB5 = 05

MB6 = FF

MB7 = 9D

MB8 = 10

MB9 = 58

=====================================

Having said that, I suggest the following commands:

  aTxBuffer[0] = 0x00;

  aTxBuffer[1] = 0x00;

  aTxBuffer[2] = 0x00;

  aTxBuffer[3] = 0x0C;

  MMA955L_AcclDataTx(aTxBuffer, 4); //Read ID command

//On Reading response

MMA955L_AcclDataRx(aRxBuffer, 16);

//Response buffer data:

0x00 0x80 0x0c 0x0c 0x7a 0xed 0x25 0x5d 0x01 0x01 0x02 0x02 0x01 0x06 0x03 0x41

(this is mainly a sanity check that communication is fine)

//Put module to awake if it was in sleep

  aTxBuffer[0] = 0x12;

  aTxBuffer[1] = 0x20;

  aTxBuffer[2] = 0x06;

  aTxBuffer[3] = 0x01;

  aTxBuffer[4] = 0x00;

  MMA955L_AcclDataTx(aTxBuffer, 5);

//Put device in legacy mode

  aTxBuffer[0] = 0x18;

  aTxBuffer[1] = 0x20;

  aTxBuffer[2] = 0x00;

  aTxBuffer[3] = 0x01;

  aTxBuffer[4] = 0x10;

  MMA955L_AcclDataTx(aRxBuffer, 5);

//Configure accelerometer

  aTxBuffer[0] = 0x04;

  aTxBuffer[1] = 0x20;

  aTxBuffer[2] = 0x00;

  aTxBuffer[3] = 0x0c;

  aTxBuffer[4] = 0x06;

  aTxBuffer[5] = 0x00;

  aTxBuffer[6] = 0x06;

  aTxBuffer[7] = 0x01;

  aTxBuffer[8] = 0x06;

  aTxBuffer[9] = 0x02;

  aTxBuffer[10] = 0x06;

  aTxBuffer[11] = 0x03;

  aTxBuffer[12] = 0x06;

  aTxBuffer[13] = 0x04;

aTxBuffer[14] = 0x06;

  aTxBuffer[15] = 0x05;

  MMA955L_AcclDataTx(aTxBuffer, 16);

//read data continuously

while(1)

{

MMA955L_AcclDataRx(aRxBuffer, 10);

}

//Response data shall looks like 04 80 0C 0C Xhigh Xlow Yhigh Ylow Zhigh Zlow

MB0 = 04

MB1 = 80

MB2 = 0C

MB3 = 0C

First for mailboxes contain the answer to previous command so are useless

MB4 = Xdata high byte

MB5 = Xdata low byte

MB6 = Ydata high byte

MB7 = Ydata low byte

MB8 = Zdata high byte

MB9 = Zdata low byte

Note 1: the data will be updated at a 30.5Hz measurement recurrence

Note 2: you may configure INT_O pin to flag when new data is available (in order to trigger an interrupt at the host MCU)

Let me know if you are successful.

Regards,     Jacques.

0 Kudos