dfskGT 0 Posted July 9, 2014 Share Posted July 9, 2014 Hello, I just received a TM4C1294XL connected launchpad. I'm trying to get it working with L3G4200D gyroscope (it's a module from Parallax with pull-ups). The program runs as expected for a while and then freezes and I have to long press the reset button to get it working again. By importing the Energia sketch into CCSv6, I was able to find the program hangs at the Wire.endtrsmission(), in particular at line //Wait for any previous transaction to complete while(ROM_I2CMasterBusBusy(MASTER_BASE)); in the Wire library. I tried with another sensor and experience the same problem. Could somebody help me out? The related code is attached below (sorry for not knowing how to format the code in the post): void setup() { // Start the Ethernet and UDP Ethernet.begin(mac,ip); udp.begin(localPort); // Start I2C Wire.setModule(0); Wire.begin(); // Initilize the L3G4200D gyro gyro.init(); } void loop() { currentTime = millis(); interval = currentTime - lastTime; if (currentTime - lastTime >= 100) { // Serial.println(interval); lastTime = currentTime; // Get sensor data gyro.getRawData(); compseTxPacket(); IPAddress remoteIP(192,168,1,10); uint16_t remoteLocalPort = 13000; udp.beginPacket(remoteIP, remoteLocalPort); udp.write(txPacketBuffer, TX_PACKET_SIZE); udp.endPacket(); } } void L3G4200D::getRawData() { while((i2cReadReg(L3G4200D_REGISTER_STATUS_REG) & 0x08) == 0); Wire.beginTransmission(L3G4200D_ADDRESS); Wire.write(L3G4200D_REGISTER_OUT_X_INC); // first register to start read from Wire.endTransmission(); Wire.requestFrom(L3G4200D_ADDRESS, 6); while(Wire.available() < 6); byte raw_low; byte raw_high; raw_low = Wire.read(); raw_high = Wire.read(); data.xRawDPS = (raw_high << 8) | raw_low; raw_low = Wire.read(); raw_high = Wire.read(); data.yRawDPS = (raw_high << 8) | raw_low; raw_low = Wire.read(); raw_high = Wire.read(); data.zRawDPS = (raw_high << 8) | raw_low; } Quote Link to post Share on other sites
zeke 693 Posted July 9, 2014 Share Posted July 9, 2014 Do you have a logic analyzer? Can you tell what state the SDA and SCL lines are in? Is the SCL being held low? Is the SDA toggling still? If yes to both above then the slave device is having trouble with your communication sequence. If this is the case then you will need to consult the datasheet for the slave device and see what it expects for a communication sequence for each command that you are sending to it. For example, if you want to read the sensor repeatedly, are you sending the correct sequence? That datasheet may say do this: 1. Write(TakeAReadingPlease) 2. Read(GiveMeTheReadingPlease) But you do this instead: 1. Write(TakeAReadingPlease) 2. Read(GiveMeTheReadingPlease) 3. Read(GiveMeTheReadingPlease) Then you can expect step 3 to fail. Why? Because the state machine inside the sensor is confused and probably in an unresponsive state until it receives one of its predetermined commands. Does that make sense? Quote Link to post Share on other sites
dfskGT 0 Posted July 9, 2014 Author Share Posted July 9, 2014 Hi zeke, thanks for the quick response. When it hangs, the SCL line stays HIGH and SDA line stays low. Do you have any comment on that? The strange thing is I'm able to get correct data for the first 2 minutes (maybe a bit longer). I checked on other's code for the same chip, I'm pretty sure the code to get raw data is OK. Any suggestions from anybody would be appreciated. Thanks! Quote Link to post Share on other sites
L.R.A 78 Posted July 10, 2014 Share Posted July 10, 2014 Hi zeke, thanks for the quick response. When it hangs, the SCL line stays HIGH and SDA line stays low. Do you have any comment on that? The strange thing is I'm able to get correct data for the first 2 minutes (maybe a bit longer). I checked on other's code for the same chip, I'm pretty sure the code to get raw data is OK. Any suggestions from anybody would be appreciated. Thanks! you sure there are pull-ups in your module? The lm4c1294 doesn't have internal pull-ups (altough i think it has in the SCL line). i find the lm4c1294 I2C very picky. I have yet to get it to work with TivaWare. But with energia i had no problem with it. What i do for srf08 sensors to avoid errors is i ask for software revision over and over, istead of just resquesting data and just wait until data comes in (wich it may never come a hang in there forever), until it gives me a clear reading, then i know i can ask the correct sensor data. Quote Link to post Share on other sites
dfskGT 0 Posted July 10, 2014 Author Share Posted July 10, 2014 I'm sure this is no a problem with pull-ups. I tried to add two 4.7k pull-ups to SDA and SCL lines. Same thing happens. And I used the following line to check if new data is available too. while((i2cReadReg(L3G4200D_REGISTER_STATUS_REG) & 0x08) == 0); It seems CCS works fine to me, but not Energia. Quote Link to post Share on other sites
zeke 693 Posted July 10, 2014 Share Posted July 10, 2014 Intuitively, I want to say that there is a problem with the Master side in its interrupt service routine - assuming the I2C Master is running with interrupts. If the Master isn't programmed to handle a specific interrupt flag that occurs then the Master will hang. Here's some troubleshooting ideas for you: 1. Check out the I2C Bus Primer. It has plenty of authoritative information on the operation of the I2C bus. 2. Compare the waveforms they present there to the waveforms that you see on your I2C bus. 3. Do you get consistent START and STOP conditions on all of your bus transactions? 4. Are you handling all Slave side interrupts for START, STOP, Receive and Transmit conditions? 5. Are you handling all Master side interrupts for START, STOP, Receive and Transmit conditions? 6. Can you sanity check your Master code by using a bit bang I2C Master rather than an interrupt driven Master? 7. Are you using a logic analyzer that can interpret I2C thus visually showing you what is happening on the bus? dfskGT 1 Quote Link to post Share on other sites
dfskGT 0 Posted July 11, 2014 Author Share Posted July 11, 2014 Thanks again for your guide. I'll look into that. However, I found that using Wire library, the read of 6 bytes takes almost 6ms. This is way too slow that I got from using modified CCS example which takes under 0.5ms. Is this a issue with the library or I did something wrong? Quote Link to post Share on other sites
L.R.A 78 Posted July 11, 2014 Share Posted July 11, 2014 can you try sometigh like this: before Wire.begin do delay(1000); Quote Link to post Share on other sites
zeke 693 Posted July 11, 2014 Share Posted July 11, 2014 I have heard from others that it is slow but I personally do not use Energia so I cannot comment on the performance of its implementation of the Wire routines. From the Slave's point of view, the speed of the CLK signal is unimportant because the Master is in control. I have worked with systems where the Master bit banged out the proper I2C protocol only it was super slow (less than 15kHz) and it worked just fine. For reference, a 100kHz CLK signal is a normal speed. I took a look at your getRawData routine and I might be inclined to rewrite it like this: void L3G4200D::getRawData() { byte rawData[6]; byte i; while((i2cReadReg(L3G4200D_REGISTER_STATUS_REG) & 0x08) == 0); Wire.beginTransmission(L3G4200D_ADDRESS); Wire.write(L3G4200D_REGISTER_OUT_X_INC); // first register to start read from Wire.endTransmission(); Wire.requestFrom(L3G4200D_ADDRESS, 6); while(Wire.available() < 6); for( i=0; i<6; i++) { rawData[i++] = Wire.read(); } data.xRawDPS = (rawData[1] << 8) | rawData[0]; data.yRawDPS = (rawData[3] << 8) | rawData[2]; data.zRawDPS = (rawData[5] << 8) | rawData[4]; } The idea is to read the I2C bus as quickly as possible and do the data processing afterwards - not in between reads. Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.