Stuck in a loop, atmega8 i2c ... - Page 1
Forum section: electronics / general

author: Raj
author_rank: Frequent Contributor
timestamp: December 16, 2016, 02:51:57 pm
content: My code is as follows-QuoteNoob problemThe ICs used areatmega8a on 8mhz clockds1307the battery backup for ds1307 reads 3.3v on multimetergot no osclloscope (or should I say its just one of those diy toy version...useless)"i2c_writer" was there just to check where and when it enters infinite loopand sure..the port b remains high and scl line reads 3mV sda reads 5v when stuck...on a multimeter

author: Brutte
author_rank: Frequent Contributor
timestamp: December 16, 2016, 04:19:34 pm
content: Quote from: Raj on December 16, 2016, 02:51:57 pmGet an AVR with debugging circuitry, stop punishing yourself.And AFAIK there is a bottom limit on clock speed on AVRs.

author: Raj
author_rank: Frequent Contributor
timestamp: December 17, 2016, 02:16:36 pm
content: Quote from: Brutte on December 16, 2016, 04:19:34 pmadvice taken....there's an arduino is on the way to my house right away.but the datasheet do say that it can work anywhere between 0hz to 8 mhzanyway...I ones had 2 circuit with same code for i2c (but with actual time outputting code added to itself) working fine (sadly i gave them away so I cant refer to them)...but somehow it doesn't work this time only.though the only difference being between all 3 being the way displays are connected to them at port b and c

author: Brutte
author_rank: Frequent Contributor
timestamp: December 17, 2016, 02:51:01 pm
content: Quote from: Raj on December 17, 2016, 02:16:36 pmArduino is undebuggable (if you mention the IDE). The environment does not offer any means of on-chip-debugging support. At least that was the case with arduino several years ago.Some AVR8's offer on-chip-debigging (OCD) circuitry that allow debugging your application step-by-step. And the i2c module from AVR8 chips is very easy to debug because it provides an extensive information about FSM states. Additionally i2c is synchronous so there are no timing limits and you can do steps one bit a time without jamming the transmission.Here is the list of the states that i2c from ATMega16 provides (embsysregview):Code:<field bitoffset="3" bitlength="5" name="TWS" description="TWI status, bits 3-7"><interpretation key="0x00" text="Bus error"/><interpretation key="0x01" text="START transmitted"/><interpretation key="0x02" text="Repeated START transmitted"/><interpretation key="0x03" text="SLA+W transmitted with ACK received"/><interpretation key="0x04" text="SLA+W transmitted with NACK received"/><interpretation key="0x05" text="Data transmitted with ACK received"/><interpretation key="0x06" text="Data transmitted with NACK received"/><interpretation key="0x07" text="Arbitration lost in SLA+W or data in Master transmitter mode"/><interpretation key="0x08" text="SLA+R transmitted with ACK received"/><interpretation key="0x09" text="SLA+R transmitted with NACK received"/><interpretation key="0x0A" text="Data received with ACK returned"/><interpretation key="0x0B" text="Data received with NACK returned"/><interpretation key="0x0C" text="Own SLA+W received with ACK returned"/><interpretation key="0x0D" text="Arbitration lost in SLA+R/W as Master, own SLA+W received, ACK returned"/><interpretation key="0x0E" text="General call address received, ACK returned"/><interpretation key="0x0F" text="Arbitration lost in SLA+R/W as Master, General call address received, ACK returned"/><interpretation key="0x10" text="Previously addressed with own SLA+W, data received, ACK returned"/><interpretation key="0x11" text="Previously addressed with own SLA+W, data received, NACK returned"/><interpretation key="0x12" text="Previously addressed with general call, data received, ACK returned"/><interpretation key="0x13" text="Previously addressed with general call, data received, NACK returned"/><interpretation key="0x14" text="A STOP or repeated START received while still addressed as slave"/><interpretation key="0x15" text="Own SLA+R received with ACK returned"/><interpretation key="0x16" text="Arbitration lost in SLA+R/W as Master, own SLA+R received, ACK returned"/><interpretation key="0x17" text="Data in TWDR transmitted with ACK received"/><interpretation key="0x18" text="Data in TWDR transmitted with NACK received"/><interpretation key="0x19" text="Last data byte in TWDR transmitted (TWEA=0) with ACK received"/><interpretation key="0x1A" text="Unknown"/><interpretation key="0x1B" text="Unknown"/><interpretation key="0x1C" text="Unknown"/><interpretation key="0x1D" text="Unknown"/><interpretation key="0x1E" text="Unknown"/><interpretation key="0x1F" text="No relevalnt state information"/></field></register>Mind only ATMega chips have real OCD with JTAG. The low end (Tinies, like ATTiny13, ATMega328 etc) have a simlified OCD that is called dW. Your cutting edge ATMega8 does not offer any OCD.

author: Ian.M
author_rank: Super Contributor
timestamp: December 17, 2016, 03:13:15 pm
content: Even the Arduino hardware has to be hacked to make it debugable + you need a debugger supported by AVR Studio. Seehttp://www.hilltop-cottage.info/blogs/adam/debugging-arduino-using-debugwire-atmel-studio-and-an-avr-dragon/

author: Raj
author_rank: Frequent Contributor
timestamp: December 17, 2016, 03:32:09 pm
content: Thanks for the help...ill try reading the error codesand thanks for the link to the arduino hack

author: Brutte
author_rank: Frequent Contributor
timestamp: December 17, 2016, 03:35:03 pm
content: Quote from: Ian.M on December 17, 2016, 03:13:15 pmOk, seems that "arduino" can be considered as either "arduino programming environment" or "arduino hardware" , one of zeveral PCBs sold under this brand, namely arduino uno, due, mini, micro whatever.Some notes:-OP's code does not look like the one from arduino programming environment - it is a plain C, possibly from avr-gcc. GCC can generate elf with debugging infrornation without a problem, it is just that OP deliberately punishes himself by dumping the output.-One cannot debug ATMega8 at all as this and many other AVR8s (attiny4) do not have OCD.-AVR8's with dW debugging interface (mostly tinies, U2 etc) require proprietary debugging dongles (sold by Atmel)-AVR8's with proper JTAG (most megas, AT90, U4, U7 etc) work with proprietary atmel dongles but also (some) work with JTAGICEMk1 clones (raw atmega16)That is why I suggest OP should get some dongle (proprietary atmel or raw atmega16) and a proper AVR8 with JTAG (atmega16, atmega32, atmega128) instead of dicking around with atmega8.

author: bktemp
author_rank: Super Contributor
timestamp: December 17, 2016, 03:56:02 pm
content: Debugging helps to find the problem, but it does not solve it. In this case, you don't need any debugger, you just need to read the datasheet:The I2C code isn't very robust: A single glitch on SCL is enough to crash the firmware: If the I2C hardware reads a single bit wrong, it thinks it has lost the arbitration and goes into a fault state not being handled by the firmware. That is probably what is happening here.If you want to make the firmware more robust, check the states returned form the I2C hardware and add a timeout. If something goes wrong, turn I2C off, manually generate at least 9 clocks on SCL followed by a stop condition. This should reset all I2C devices. Then reinitializes and switch the I2C module back on.

author: Kalvin
author_rank: Super Contributor
timestamp: December 17, 2016, 04:09:43 pm
content: You should add something like this in your code containing those loops in order to make it more robust:void i2c_writer(unsigned char data){uint16_t i2c_timeout_counter = 0;TWDR=data;TWCR=0b10000100;while ((!(TWCR & 0x80))&& (i2c_timeout_counter < I2C_TIMEOUT_COUNT)){PORTB=0xFF;i2c_timeout_counter++;}if (i2c_timeout_counter >= I2C_TIMEOUT_COUNT){/* i2c timeout: something bad has happened */}}Now the loop will eventually terminate if the hardware gets stuck and you have an opportunity to catch the fault and do something about it - like print an error message and make other suitable actions.

author: Raj
author_rank: Frequent Contributor
timestamp: December 17, 2016, 04:32:25 pm
content: Quote from: Kalvin on December 17, 2016, 04:09:43 pmWow, that took away a lot of work,thanks!

author: TiN
author_rank: Super Contributor
timestamp: December 17, 2016, 05:44:09 pm
content: Check your wiring on I2C port, make sure you have correct pullup on I2C SDA and SCL and check that port is configured correctly. If I2C hardware not working, your I2C block will be waiting forever for state to change.

author: Brutte
author_rank: Frequent Contributor
timestamp: December 17, 2016, 08:24:54 pm
content: I'd say that writing an application that run-time manages glitches over i2c means you are heading in the wrong direction.Either the bus is operational with no transmission errors or there is something bad in your design. The i2c timeout problem just shows you do not understand the purpose of i2c. There is no CRC or even parity check in this protocol. How do you expect to exchange any data over i2c (to sensors, memories etc) if your bus has transmission errors?

author: Raj
author_rank: Frequent Contributor
timestamp: December 18, 2016, 05:51:36 am
content: ok here's the error code i receive with above code....its the same if i remove the ds1307 from circuit entirelyIn portB,the output becomes 01001,indicating the tws value is 01001000ie-SLA+R transmitted with NACK received as per the guide presented by BrutteSo i guess i'll have to order a new RTCbtw the pull up resistors were 10k later changed to 4.7k

author: Raj
author_rank: Frequent Contributor
timestamp: December 18, 2016, 07:58:03 am
content: wait a second..that isn't right... the clock lines go low and remains low after the transmission of slave address is completeThis happens even when the rtc is not connectedBtw...the rtc ic is not an original ds1307 but a ripoff/copy ie vs1307

author: bktemp
author_rank: Super Contributor
timestamp: December 18, 2016, 09:18:00 am
content: Quote from: Raj on December 18, 2016, 07:58:03 amThat is because the I2C module is in "SLA+R has been transmitted; NOT ACK has been received" state and needs further instructions what to do.Look at the table in the datasheet, the last column shows what to do: "Next Action Taken by TWI Hardware"For 0x48 it says:QuoteThe I2C module is still the bus master and uses the bus. You need to send a stop to set the I2C bus back to idle state.

author: Raj
author_rank: Frequent Contributor
timestamp: December 18, 2016, 09:51:36 am
content: Quote from: Raj on December 18, 2016, 07:58:03 amfunny thing is,i2c_init();i2c_start();i2c_write(0x0D); <==== this is where it gets stucki2c_write(0); <this instruction is not being executed at all unless I change "i2c_write(0x0D);" to i2c_writer(0x0D);i2c_write(0);i2c_write(0);i2c_write(0);i2c_stop();how do I know that?I changed i2c_write as followsQuoteand main toQuotethe output of portb and c becomes as follows-portb=0x01001 ie tws =01001000ie-SLA+R transmitted with NACK received as per the guide presented by Brutteport c=00001101 when it enters infinite loopMaybe I should take a break until I get my arduino thus the ability to serially output the states of various registers

author: Raj
author_rank: Frequent Contributor
timestamp: December 23, 2016, 07:56:13 am
content: Changed the rtc and it works fine after a little tweaking....the old rtc chips somehow died in storage. don't know why

author: stfsux
author_rank: Contributor
timestamp: December 25, 2016, 12:32:11 pm
content: Raj against the RTC