Having trouble in communication between MMA8451 and MKW2x series platform

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

Having trouble in communication between MMA8451 and MKW2x series platform

1,569 Views
吕晨赵
Contributor I

Hi everyone .I have trouble in communication between MMA8451 and MKW2x series platform.I have got something from MMA8451 through I2C bus.

Originally, I have tried to modify the driver code generated by the Beekit. It is based on the interrrupt system and seems didn't work.So I gave up the driver and used registers of  i2c module directly.According to the document I use these registers addresses and values and got the correct device id(default value 0x1A) .But there is still some problems.

1. All accelerometer data seems not changed whether I shaked accelerometers or not.It is X_MSB 0x43,Y_MSB 0x20,Z_MSB 0x56,and Z_LSB 0x48.

2 The code like this  is working fine step by step.But it got stuck when I run it without stop.

I guess I need delay for a while after writing or reading the I2C1_D(data register). It still got stuck sometime,but better than no delay.

So,these two problems, any suggestion?

Thanks!

All the registers and its value's meaning is described in the MKW2xD Reference Manual and MMA8451Q data sheet.Before the code,I have already done the init work.If someone needs the init code, I'll post it later.

while(1){
    /***************start signal*****************/
    I2C1_C1 |= 0x20u;//set master mode
    I2C1_C1 |= 0x10u;//set transmit mode
    I2C1_C1 |= 0x8u; //set txak mode
   
    /********write byte to the IIC bus**********/
    I2C1_D = 0x38;
    /********wait flag*******************/
    while((I2C1_S & 0x2u)==0);
    I2C1_S |= 0x2u;
    /****************get ack signal**********/
    while((I2C1_S & 0x1u));
   
    /*****************get byte from XYZ registers****************************************/
    I2C1_D = buf[Index];
    Index = (Index+1)%9;
    while((I2C1_S & 0x2u)==0);
    I2C1_S |= 0x2u;
    while((I2C1_S & 0x1u));
    /****************************************************************/
   
    /****************repeated start signal***************************/
    I2C1_C1 |= 0x04u;
    I2C1_D = 0x39;

    while((I2C1_S & 0x2u)==0);
    I2C1_S |= 0x2u;
    while((I2C1_S & 0x1u));
    /********set rx mode********/
    I2C1_C1 &= ~0x10u;
    /******give nack***********/
    I2C1_C1 |= 0x8u;
    /******read data from IIC bus*****/
    results = I2C1_D;
    /***********WAIT****************/
    while((I2C1_S & 0x2)==0);
    I2C1_S |= 0x2u;
    /**********STOP*******************/
    I2C1_C1 &= ~0x20u;
    I2C1_C1 &= ~0x10u;
   
    results =I2C1_D;
    for(n=0;n<IDLE_LOOP;n++)
      asm("nop");
   
    iLoop++;  
  }

0 Kudos
3 Replies

848 Views
AngelC
Senior Contributor I

Hello,


The Ultra low cost ZigBee Evaluation Board package contains sample software interfacing the MKW24D512 and a FXOS8700, which should be very similar to the MMA8451 accelerometer. The software was developed based in SMAC wireless UART. You may use the I2C part of it for your project and change the register values of FXOS8700 to match the MMA8451 ones. It has been used without problems.


Link: Ultra Low Cost Zigbee Evaluation Board


You may also download the FRDM-KL25Z and TWRKL25Z48M Sample Code Package, which contains a baremetal I2C driver and functions to read the MMA8451 (FRDM_KL25ZDemo folder). You may need to update the register definitions to match those of MKW2x.


Regards,

AngelC

0 Kudos

847 Views
吕晨赵
Contributor I

Hi, I have tried something similiar before. And it works.But there are still some problems.

The sample code doesn't use interrupts which is important to me, because I need to do something else while reading data from sensors.The driver code I have mentioned before includes interrupt routine, tansmit and receive functions. And it works except for the reading function. All the data I got is 0xff.(I didn't find this situation using the sample code).When I debugged it by steps, I found real data was received and stored in the I2Cx_D registers. But after dummy read steps, all data was set to 0xff. Then no different data was received after that. I2Cx_D register's value is always 0xff.So what's the problem?Can you give me some suggestion?

ps: Its flowchart and interrupt routine code is below.

void IIC_Isr

(

void

)

{

register uint8_t dummy;

/* Clear the interrupt request */

I2Cx_S |= I2C_S_IICIF_MASK; /* clear the interrupt request flag by writing a "one" to it */

/* Check arbitration and slave addressing */

if (I2Cx_S & (I2C_S_ARBL_MASK | I2C_S_IAAS_MASK ))

{

if (I2Cx_S & I2C_S_IAAS_MASK) /* Addressed as slave */

{

/* Check if I2C module was addressed for read or for write */

if(I2Cx_S & I2C_S_SRW_MASK) /* slave TRANSMIT (master reading from slave) */

{

/* Configure I2C module for TX operation. Writing to I2Cx_C1 register also clears IAAS bit */

I2Cx_C1 |= I2C_C1_TX_MASK; /* set I2Cx_C1[TX] */

/* Send next byte from the current Tx buffer */

IIC_SendNextByte();

}

else /* slave RECEIVE (master writing to slave) */

{

/* Configure I2C module for RX operation. Writing to I2Cx_C1 register also clears IAAS bit */

I2Cx_C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);

/* dummy read of data register */

//dummy = I2C0_D;I2C0

//tmp = I2C1_D;

dummy = I2C1_D;

(void)dummy;

}

}

if(I2Cx_S & I2C_S_ARBL_MASK) /* Arbitration lost */

{

I2Cx_S |= I2C_S_ARBL_MASK; /* clear arbitration lost flag */

if(mIICMasterOp.iicOpType == mIIC_OpType_Tx_c)

{

if(pfIIcMasterTxCallBack)

{

TS_SendEvent(gIIcTaskId, gIIC_Event_MasterTxFail_c);

}

}

else

{

if(pfIIcMasterRxCallBack)

{

TS_SendEvent(gIIcTaskId, gIIC_Event_MasterRxFail_c);

}

}

}

}

else /* Arbitration okay */

{

/* Check addressing */

if (I2Cx_C1 & I2C_C1_MST_MASK) /* MASTER mode */

{

if (I2Cx_C1 & I2C_C1_TX_MASK) /* (MASTER) TRANSMIT mode */

{

if (I2Cx_S & I2C_S_RXAK_MASK) /* NACK received */

{

/* generate STOP condition and configure the module as receiver */

I2Cx_C1 &= ~(I2C_C1_MST_MASK | I2C_C1_TX_MASK);

if(mIICMasterOp.iicOpType == mIIC_OpType_Tx_c) /* TX */

{

if(pfIIcMasterTxCallBack)

{

TS_SendEvent(gIIcTaskId, gIIC_Event_MasterTxFail_c);

}

}

else /* RX */

{

if(pfIIcMasterRxCallBack)

{

TS_SendEvent(gIIcTaskId, gIIC_Event_MasterRxFail_c);

}

}

}

else /* ACK received */

{

if(mIICMasterOp.iicOpType == mIIC_OpType_Rx_c) /* RX */

{

/* send ACK response for next bytes */

I2Cx_C1 &= ~(I2C_C1_TX_MASK | I2C_C1_TXAK_MASK);

if(mIICMasterOp.bufLen-- == 1)

{

/* send NACK response for last byte */

I2Cx_C1 |= I2C_C1_TXAK_MASK;

}

/* dummy read of data register */

//dummy = I2C0_D; i2c0

//tmp = I2C1_D;

dummy=I2C1_D;

(void)dummy;

}

else /* TX */

{

if(mIICMasterOp.bufLen) /* more data to be transmitted */

{

/* write next byte to I2C data register */

//I2C0_D = *mIICMasterOp.pBuf++ ;I2C0

I2C1_D=*mIICMasterOp.pBuf++ ;

/* decrement the buffer size */

mIICMasterOp.bufLen--;

}

else /* last data byte transmitted */

{

/* generate STOP condition; after STOP I2C module is in slave mode */

I2Cx_C1 &= ~(I2C_C1_MST_MASK | I2C_C1_TX_MASK);

if(pfIIcMasterTxCallBack)

{

TS_SendEvent(gIIcTaskId, gIIC_Event_MasterTxSuccess_c);

}

}

}

}

}

else /* (MASTER) RECEIVE mode */

{

if(mIICMasterOp.bufLen == 0) /* last byte received */

{

/* generate STOP condition; after STOP I2C module is in slave mode */

//I2Cx_C1 &= ~I2C_C1_MST_MASK;

I2Cx_C1 &= ~(I2C_C1_MST_MASK | I2C_C1_TX_MASK);

if(pfIIcMasterRxCallBack)

{

TS_SendEvent(gIIcTaskId, gIIC_Event_MasterRxSuccess_c);

}

}

else if(mIICMasterOp.bufLen-- == 1) /* next to last byte to receive */

{

/* send NACK response for last byte */

I2Cx_C1 |= I2C_C1_TXAK_MASK;

}

//*mIICMasterOp.pBuf++ = I2C0_D;I2C0

// testbuf[test_index]=I2C1_D & 0xff;

// *mIICMasterOp.pBuf++ = testbuf[test_index] & 0xff;

// test_index = (test_index+1)%3500;

//tmp =I2C1_D;

*mIICMasterOp.pBuf++ = I2C1_D;

}

}

else /* SLAVE mode*/

{

if (I2Cx_C1 & I2C_C1_TX_MASK) /* (SLAVE) TRANSMIT mode */

{

/* IIC has transmmited a byte to the master. Check if ack was received */

if (I2Cx_S & I2C_S_RXAK_MASK) /* ACK not received */

{

/* No ack received. Switch back to receive mode */

I2Cx_C1 &= ~I2C_C1_TX_MASK;

/* dummy read of data register */

//dummy = I2C0_D;

//tmp = I2C1_D;

dummy =I2C1_D;

(void)dummy;

}

else

{

/* Ack received. Send next byte */

IIC_SendNextByte();

}

}

else /* (SLAVE) RECEIVE mode */

{

/* Put the received byte in the buffer */

if(pfIIcSlaveRxCallBack)

{

IIC_PushData(&mIIcRxBuf, I2C0_D);

/* Let the application know a byte has been received. */

TS_SendEvent(gIIcTaskId, gIIC_Event_SlaveRx_c);

}

else

{

/* dummy read of data register */

//dummy = I2C0_D;

//tmp = I2C1_D;

dummy=I2C1_D;

(void)dummy;

}

}

}

}

}

Lyuchen Zhao

From: AngelC

Date: 2015-04-20 17:52

To: 吕晨 赵

Subject: Re: - Having trouble in communication between MMA8451 and MKW2x series platform

Having trouble in communication between MMA8451 and MKW2x series platform

reply from AngelC in Kinetis Microcontrollers - View the full discussion

Hello,

The Ultra low cost ZigBee Evaluation Board package contains sample software interfacing the MKW24D512 and a FXOS8700, which should be very similar to the MMA8451 accelerometer. The software was developed based in SMAC wireless UART. You may use the I2C part of it for your project and change the register values of FXOS8700 to match the MMA8451 ones. It has been used without problems.

Link: Ultra Low Cost Zigbee Evaluation Board

You may also download the FRDM-KL25Z and TWRKL25Z48M Sample Code Package, which contains a baremetal I2C driver and functions to read the MMA8451 (FRDM_KL25ZDemo folder). You may need to update the register definitions to match those of MKW2x.

Regards,

AngelC

Did your question get answered?

If so, say thanks by clicking Correct Answer in the community thread!

Reply to this message by replying to this email, or go to the message on Freescale Community

Start a new discussion in Kinetis Microcontrollers by email or at Freescale Community

Following Having trouble in communication between MMA8451 and MKW2x series platform in these streams: Inbox

0 Kudos

847 Views
AngelC
Senior Contributor I

I modified BeeStack ZHA GenericApp I2C driver to use a FXOS8700 sensor. This is very similar to MMA8451, so the same code could be used for it. There might be several ways to implement a FXOS8700 driver, ones better than others, but this simple yet useful approach may help you with your implementation.

Link: https://community.freescale.com/docs/DOC-104825

Please notice the example is provided as is, and the support of it is limited. Significant changes to the original template could be identified with “FXOS8700 demo”. I hope it helps.

Regards,

AngelC

0 Kudos