MPL3115A2 with EK-TM4C123GXL not working properly

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

MPL3115A2 with EK-TM4C123GXL not working properly

1,794 Views
matthewfr
Contributor II

Hello,

i'm using MPL3115A2 with EK-TM4C123GXL launchpad. I created code to signle read and mulitread to communicate with sensor. My problem is that i can't communicate with sensor when i'm not debugging code - when i download code to launchpad and check everyline in code ( F6 step over) everything works perfect. I'm able to read all registers that i need. - so next in debug mode i run program and it's works fine - i can see received values in terminal. Problem appears when i turn off launchpad and turn it on back (ofcorse programed). I can't see any values in terminal (only 0's), so then i debugg code again - when i press run in debugg mode it also doesn;t work, but when i reset uC, check 1st line where i read sensor ID and then run program, it works again. I will add that i try to read sensor in Timer ISR - timer is trigered 4 times per sec.

i'm trying to fix this but i cant find any reason what is going on. Here's osciliscope screen:

1st - when i can't communicate with sensor

T0003.PNG.png

2nd - single read and double read after uC reset, check everyline and then run:

T0004.PNG.png

T0005.PNG.png

Hope you will give me some advice, here's how i setup sensor:

k=i2c_write(0x60, 0x26,0x00);

        k=i2c_write(0x60, 0x26,0xB9);

        k=i2c_write(0x60, 0x27,0x02);

        i2c_read(0x60,0x26, &k);

        i2c_read(0x60,0x27, &k);

and here's mu functions

/////////////////////read data from i2c addre - is address of sensor 0x60, data is register

void i2c_read(char addre, unsigned long data,short *receive){

  unsigned long k=0;

  I2CMasterSlaveAddrSet(I2C1_BASE,addre,false); //setup slave address with last bit 0

  I2CMasterDataPut(I2C1_BASE,data); //put data

  I2CMasterControl(I2C1_BASE,I2C_MASTER_CMD_BURST_SEND_START); // start transmistion

  while(!I2CMasterBusy(I2C1_BASE)); //wait when bus is busy

  while(I2CMasterBusy(I2C1_BASE));

  I2CMasterSlaveAddrSet(I2C1_BASE,addre,true); //setup address again

  I2CMasterControl(I2C1_BASE,I2C_MASTER_CMD_SINGLE_RECEIVE); //start receive data

  k=I2CMasterErr(I2C1_BASE);

  while(I2CMasterBusy(I2C1_BASE));

  while(I2CMasterBusy(I2C1_BASE));

tab[0]=I2CMasterErr(I2C1_BASE); //check errors

  k=I2CMasterDataGet(I2C1_BASE); // take data

  *receive=k;

  I2CMasterControl(I2C1_BASE,I2C_MASTER_CMD_BURST_RECEIVE_FINISH);

////////////write to sensor///

}

unsigned long i2c_write(char address, unsigned long reg,unsigned long data){

  unsigned long k=0;

  I2CMasterSlaveAddrSet(I2C1_BASE,address,false); //setup slave address with last bit 0

  I2CMasterDataPut(I2C1_BASE,reg); //put data reg address

  I2CMasterControl(I2C1_BASE,I2C_MASTER_CMD_BURST_SEND_START); // start transmistion

  while(!I2CMasterBusy(I2C1_BASE));

  while(I2CMasterBusy(I2C1_BASE));

  k=I2CMasterErr(I2C1_BASE);

  I2CMasterDataPut(I2C1_BASE,data); // data to write

  k=I2CMasterErr(I2C1_BASE);

  I2CMasterControl(I2C1_BASE,I2C_MASTER_CMD_BURST_SEND_FINISH); //finish

  k=I2CMasterErr(I2C1_BASE); //check error

return k;

}

void i2c_multi_read(char address, unsigned data, unsigned repeat, short tab[] ){

  unsigned long k=0,err=0,i=0;

  I2CMasterSlaveAddrSet(I2C1_BASE,address,true); //false

  I2CMasterDataPut(I2C1_BASE,data);

  I2CMasterControl(I2C1_BASE,I2C_MASTER_CMD_BURST_SEND_START);

  while(I2CMasterBusy(I2C1_BASE));

  while(I2CMasterBusy(I2C1_BASE));

  I2CMasterSlaveAddrSet(I2C1_BASE,address,true);

  I2CMasterControl(I2C1_BASE,I2C_MASTER_CMD_BURST_RECEIVE_START );

  SysCtlDelay(10);

    while(I2CMasterBusy(I2C1_BASE));

  while(I2CMasterBusy(I2C1_BASE));

  tab[0]=I2CMasterDataGet(I2C1_BASE);//no dummy read

  tab[5]=I2CMasterErr(I2C1_BASE);

  for(i=0;i<repeat;i++){

  I2CMasterControl(I2C1_BASE,I2C_MASTER_CMD_BURST_RECEIVE_CONT);

  //while(!I2CMasterBusy(I2C1_BASE));

  while(I2CMasterBusy(I2C1_BASE));

  while(I2CMasterBusy(I2C1_BASE));

  SysCtlDelay(10);

  tab[i+1]=I2CMasterDataGet(I2C1_BASE);

  if (I2CMasterErr(I2C1_BASE)!=0){tab[6]=I2CMasterErr(I2C1_BASE);}

  }

  I2CMasterControl(I2C1_BASE,I2C_MASTER_CMD_BURST_RECEIVE_FINISH);

}

Labels (1)
8 Replies

1,030 Views
Joshevelle
Senior Contributor I

Hello M Poz,

Please notice that the MPL3115A has a turn on time of ~60mS at its highest speed mode and ~1000mS at highest resolution mode.

The speed mode is set on the OS bits of the CTRL_REG1 (0x26), you send 0x00 to that register, hence since OS=000, the oversample ratio is 6m which equals to highest speed mode.

For details, please take a look at table 58, page 31 of the following document:

http://cache.freescale.com/files/sensors/doc/data_sheet/MPL3115A2.pdf

Looking at the 1st oscilloscope screen, I noticed that the IIC communication starts at ~50mS, which is less than the MPL3115A startup time.


I would recommend you to add a delay before trying to communicate with the sensor. You could either add a 1 second delay so you can set the OS to any desired oversampling rate, or add a required delay depending on the OS.


Hope it helps, have fun!


Josh

1,030 Views
matthewfr
Contributor II

Hello,

thank you for answer. I found problem - i think - there was no delay betwen reads of sensor so that was why everytime i got 0x10 error. After the end signal i added one more loop and it helps

I got one more question.

I setup up mpl3115a2 as follows:

k=i2c_write(0x60, 0x26,0x04);//reset registers

        k=i2c_write(0x60, 0x26,0xB8); //b9 one shot //

        k=i2c_write(0x60, 0x13,0x07);

        k=i2c_write(0x60, 0x28,0x32); //0X31

        k=i2c_write(0x60, 0x29,0x80);

        k=i2c_write(0x60, 0x26,0xB9); // above

uC pins are setup as inputs open drain/pull-down.

Maybe i dont undarstand datasheet in 100% but after setup mpl3115a2 sensors like above, i expect that it will generate interrupt on pin every time when data is redy ( every 512 ms) am i right? I'm asking because sensor generate interrupts on pin very often which cause that uC only handling gpio isr - so it cant come back to main loop because it's came back to gpio isr.

0 Kudos

1,030 Views
Joshevelle
Senior Contributor I

You're welcome.

Do you have both interrupts connected to the MCU pins?

The MCU pins are set to pull-down, so it means the MCU will have an GPIO ISR if one of the input pins changes its status to high.

in CTRL_REG3 (0x28), you wrote 0x32. Which equals to:

IPOL_1 = 1;     <--- Active High :smileycheck:

PP_OD1 = 1;   <--- Open drain :smileycheck:

IPOL_2 = 1;     <--- Active High  :smileycheck:

PP_OD2 = 0;   <--- Internal Pull-Up enabled :smileyx:

The internal pull up for the interrupt 2 is enabled, which means that the MCU will always have a GPIO ISR.

I would recommend you to set  CTRL_REG3 to 0x33

Josh

0 Kudos

1,030 Views
matthewfr
Contributor II

Thank you for answer.

i did what you recomend. uC inputs are setup as weak pull-down and gpio interrupt trigger mechanism  is setup to GPIO_BOTH_EDGES - any change of state triggers interrupt.

CTRL_REG3 is set to 0x33. CTRL_REG5 is set to 0x00 - so it means all interrupts are routed to int2 pin.

Now when i check int1 int2 pins both are in high state. So when i connect them to uC they trigers gpio isr. Regard to this setup - is it int1 pin state should be as logical 0 not 1 ? it's not used as interrupt source because all interrupts are routed to int2 pin, so i think it should be in 0 state. but It's always high.

in my setup how many times sensor will be generating interrupt on int2 pin ?

0 Kudos

1,030 Views
Joshevelle
Senior Contributor I

Every time the sensor sends an interrupt you would need to read the INT_SOURCE register (0x12) to look for the interrupt source.

please take a look at page 25 - 26 of the datasheet.

http://www.freescale.com/files/sensors/doc/data_sheet/MPL3115A2.pdf

the data ready bit would be "SRC_DRDY":

""Data ready interrupt status bit. Logic ‘1’ indicates that Pressure/Altitude or Temperature data ready interrupt is active indicating the presence of new data and/or a data overwrite, otherwise it is a logic ‘0’.
This bit is asserted when the PTOW and/or PTDR is set and the functional block interrupt has been enabled.
This bit is cleared by reading the STATUS and Pressure/Temperature register. ""


Hope it helps.

Josh

0 Kudos

1,030 Views
matthewfr
Contributor II

hello,

i setup sensor for interrupt read like in dt on page 10. uC intput pins are setup as GPIO_PIN_TYPE_STD_WPD (weak pull down) and trigger source is high_level

My setup is

k=i2c_write(0x60, 0x26,0x04);//reset registers

        k=i2c_write(0x60, 0x26,0xB8);

        k=i2c_write(0x60, 0x13,0x07);

        k=i2c_write(0x60, 0x28,0x33);

        k=i2c_write(0x60, 0x29,0x80);

        k=i2c_write(0x60, 0x26,0xB9);

in gpio isr routine i read:

i2c_read(0x60,0x06, &k);

  i2c_read(0x60,0x12, &k);

  i2c_multi_read(0x60,0x00, 6, i2c_rec); // reads from 0x00 to 0x05

uC is still stoped on gpio isr. Can you point me what is wrong ?

0 Kudos

1,030 Views
Janosch
Contributor II

Hi M Poz,

this certainly seems to be an issue of your LaunchPad environment, and i would advise you to go to the TI e2e community and ask for help. They are very quick there and will look at your code. http://e2e.ti.com/support/microcontrollers/tiva_arm/f/908.aspx

I briefly checked your code, and it actually looks very similar to mine running code (however i use a different sensor). I'm sure if you post your problem just like this in that forum, you'll get help very soon.

Do you also want to try my code?

Cheers

Janos 

0 Kudos

1,030 Views
matthewfr
Contributor II

Yes, please send it to me.

0 Kudos