The official Mbed 2 C/C++ SDK provides the software platform and libraries to build your applications.
Dependents:
hello
SerialTestv11
SerialTestv12
Sierpinski
... more
14 comments:
You are my hero!
I had this Problem since the beginning of developing my quadrocopter... When updating the sensor data via I2C while the remote control gives me a PPM-Signal (which I measure with short interrupts) I realized some collisions. If the repeated flag isn't set the mbed stalls when the first collision occures. When I set the repeated flag (last parameter of the I2C routines) the mbed doesn't stall anymore but there are some extreme values randomly spread when reading the sensors.
Could you give me a hint how I can compile my program with the line you mentioned fixed until the fix is generally released? Is it possible with the Online-Compiler?
I just compiled my program with LPCXpresso v4.3.0_1023 to give it a try but there the mbed library also is just an object file so I can't change anything...
Thanks in advance, looking forward to a stable flying quadrocopter :)
Thanks Helmut, this is a brilliant bug report. We will reproduce and fix this issue in the mbed library.
Cheers,
Emilio
Hi Matthias,
yes, it is possible to build your project with your own modified mbed library. First you have to remove the precompiled mbed lib from your project. Then import the mbed-NXP and mbed-src libraries, apply the fix and rebuild your project. This works fine with the online-compiler. You can use program referenced in the issue report as an example.
cheers,
Helmut
Thx for your advice, I took your example program, copied my code into it, commented the line you mentioned but it was still not the solution for my problem. It showed the normal sensor values and i didn't have this random peeks everywhere but some rare peeks that were much higher... (don't ask me why, sadly i have no logic analyser)
I decided to try the MODI2C, which works perfectly when I initialised the control registers of the sonsors with the orgininal mbed I2C-library before. So my solution/hack/workaround is now to use the original I2C (untouched) to initialise the individual control registers (write one at a time) and to use MODI2C for the usual data getting method (get all the 6 regs of data at a time).
for code see here (line 30) : http://mbed.org/users/maetugr/code/FlyBed1/file/128c55793728/Sensors/I2C_Sensor.cpp
thx for publishing all the info, that really helps to find a solution :)
Hi Matthias,
I don't have yet a good setup in place to reproduce your issue, but looking at the code I've found this in i2c_api.c/i2c_send_stop:
inline void i2c_stop(i2c_t *obj) {
// write the stop bit
i2c_conset(obj, 0, 1, 0, 0);
i2c_clear_SI(obj); // --------------------> comment this line
// wait for STO bit to reset
while(I2C_CONSET(obj) & (1 << 4));
}
I can still see an i2c_clear_SI call in this function. Could you please comment that line and see if anything changes?
OK, my previos suggestion doesn't work, so you can disregard it completely. I wrote a small test that writes a predefined value at a fixed address in an I2C 24LC256 EEPROM and then reads this value and compares it with the written value in a loop (for 100000 times). The loop looks like this:
data[0] = data[1] = 0;
if((status = i2c.write(addr, data, 2, true)) != 0)
{
printf("Test %d failed at write, status is %02X\r\n", i, status);
fw ++;
continue;
}
// wait_us(30);
if((status = i2c.read(addr, data, 1)) != 0)
{
printf("Test %d failed at read, status is %02X\r\n", i, status);
fr ++;
continue;
}
if(data[0] != mark)
{
printf("Test %d failed at data match\r\n", i);
fc ++;
}
These are my findings:
- no RTOS, using the standard mbed-NXP lib: no errors
- with mbed-rtos added to the project. using the standard mbed-NXP lib: no errors
- no RTOS, using the standard mbed-NXP lib and uncommenting the "wait_us" line above: lots of errors
- no RTOS, using Helmut's fix and wait_us: no errors
- RTOS, using Helmut's fix and wait_us: no errors
So Helmut's fix is obviousy right. That said, Matthias, I don't know why you're still getting errors. It seems that I can't reproduce this locally, not yet at least.
Not sure if this will help or confuse matters but I had seen the same intermittent behavior (this was before the SDK source was available).
In my case, Tickers we're causing the problem during i2c transactions. Disabling global IRQ's during i2c read/write fixed this temporarily but is far from ideal.
Just a suggestion for your testing. I was using the LPC11U24, no RTOS. But I think your wait_us is a more reliable way of jamming this up.
Hello Sam,
Thanks for your reply! A few questions below:
Not sure if this will help or confuse matters but I had seen the same intermittent behavior (this was before the SDK source was available).
In my case, Tickers we're causing the problem during i2c transactions. Disabling global IRQ's during i2c read/write fixed this temporarily but is far from ideal.
Just a suggestion for your testing. I was using the LPC11U24, no RTOS. But I think your wait_us is a more reliable way of jamming this up.
- When you were using tickers, was there some other part of you code that called I2C functions?
- If you still have that code, would it be possible to apply Helmut's patch (and comment out the code that disables/enables global interrupts) and check if you still have this problem? That would be very helpful.
Thanks,
Bogdan
When you were using tickers, was there some other part of you code that called I2C functions?
Yes - The Tickers just run state machines for diagnostic LED's and other state of health type of tasks (counters, events and such). The I2C calls were made from the main loop (or a few calls from it)
If you still have that code, would it be possible to apply Helmut's patch (and comment out the code that disables/enables global interrupts) and check if you still have this problem? That would be very helpful.
Let me try and dig up some hardware. I'll get back to you by the end of the day either way.
@ Bogdan Marinescu
I didn't have any luck finding hardware today (this is on a production PCB now using the LPC11U37 - 32k wasn't enough memory). I'll try to see if there is a failure PCB that can be resurrected next week.
Thanks a lot for your help. I hope you find some hardware that you can test this on.
Thanks a lot for your help. I hope you find some hardware that you can test this on.
I was able modify hardware and get some further testing done. In my case the original symptom was intermittent but I was able to force a failure by adding wait_us(50);
void CAT5132::readWiperPosition( int8_t &position )
{
// prepare the access control register
writeACR();
wait_us(50); // <- causes a failure at some point... not the first pass though
position = read();
return;
}
I had also gone back to creating transactions with using the start(), write(), start(), read(), stop()
api methods which don't call int i2c_write(i2c_t *obj, int address, const char *data, int length, int stop)
in ./hal/i2c_api.c and don't seem to have the same problem.
Anyways, commenting out line #261 i2c_clear_SI(obj);
in /vendor/NXP/LPC11U24/hal/i2c_api.c does appear to be a fix. Here are a few pictures from my logic analyzer (in my project the failure appears to sit in an infinite loop at inline void i2c_stop(i2c_t *obj)
only allowing IRQ context functions to run).
mbed-src revision 10 (Code Failing):
The hardware i'm working with doesn't have good debug hooks so getting more information (ie: register values) will be painful. I ran this through 500k+ transactions with Helmut's patch and no failures thus far.
Looking at Matthias' response, am I correct that MODI2C doesn't suffer from the issue? (Otherwise I have to fix it :P)
The reason the byte is rewritten to i2c bus is that in case of a repeated start the START flag should be set before SI flag is cleared. MBED libray did it the other way around. Deleting the i2c_clear_SI(obj); is not a proper fix.
You are my hero! I had this Problem since the beginning of developing my quadrocopter... When updating the sensor data via I2C while the remote control gives me a PPM-Signal (which I measure with short interrupts) I realized some collisions. If the repeated flag isn't set the mbed stalls when the first collision occures. When I set the repeated flag (last parameter of the I2C routines) the mbed doesn't stall anymore but there are some extreme values randomly spread when reading the sensors.
Could you give me a hint how I can compile my program with the line you mentioned fixed until the fix is generally released? Is it possible with the Online-Compiler? I just compiled my program with LPCXpresso v4.3.0_1023 to give it a try but there the mbed library also is just an object file so I can't change anything...
Thanks in advance, looking forward to a stable flying quadrocopter :)