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
2nd - single read and double read after uC reset, check everyline and then run:
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);
}
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
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.
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
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 ?
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
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 ?
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
Yes, please send it to me.