Author Topic: Stuck in a loop, atmega8 i2c ...  (Read 5810 times)

0 Members and 1 Guest are viewing this topic.

Offline RajTopic starter

  • Frequent Contributor
  • **
  • Posts: 702
  • Country: in
  • Self taught, experimenter, noob(ish)
Stuck in a loop, atmega8 i2c ...
« on: December 16, 2016, 02:51:57 pm »
My code is as follows-
Quote
#include <avr/io.h>
#include <util/delay.h>
#include <util/twi.h>
#include <util/twi.h>


//*****************************************************************
void i2c_init(void)
{
   TWSR=0X00;
   TWBR=0X47;
   TWCR=0X04;
}
//*****************************************************************
void i2c_start(void)
{
   TWCR = 0b10100100;
   while (!(TWCR & 0x80));
}
//*****************************************************************
void i2c_write(unsigned char data)
{
   TWDR=data;
   TWCR=0b10000100;
   while (!(TWCR & 0x80));
}

//*****************************************************************
void i2c_stop()
{
   TWCR = 0b10010100;
   for (int k=0; k<100; k++);
   
}
//*****************************************************************
unsigned char i2c_read(unsigned char ackVal)
{
      TWCR = 0b11000010;
      while (!(TWCR & 0x80));
      return TWDR ;
}

//*****************************************************************
void i2c_writer(unsigned char data)
{
   TWDR=data;
   TWCR=0b10000100;
   while (!(TWCR & 0x80)){
        PORTB=0xFF;}
}


int main (void)
{
   DDRB=0b00111111;
   DDRC=0b00001111;
   unsigned char q=0;
   unsigned char a,b;

   i2c_init();
   i2c_start();
   i2c_write(0x0D);
   i2c_writer(0);
   PORTB=0X00;
   i2c_write(0);
   i2c_write(0);
   i2c_write(0);
   i2c_stop();
   

Noob problem

The ICs used are
atmega8a on 8mhz clock
ds1307

the battery backup for ds1307 reads 3.3v on multimeter :-DMM
got no osclloscope (or should I say its just one of those diy toy version...useless) :-BROKE

"i2c_writer" was there just to check where and when it enters infinite loop
and sure..the port b remains high and scl line reads 3mV sda reads 5v when stuck...on a multimeter

« Last Edit: December 16, 2016, 02:56:30 pm by Raj »
 

Offline Brutte

  • Frequent Contributor
  • **
  • Posts: 614
Re: Stuck in a loop, atmega8 i2c ...
« Reply #1 on: December 16, 2016, 04:19:34 pm »
atmega8a on 8mhz clock
Get an AVR with debugging circuitry, stop punishing yourself.
And AFAIK there is a bottom limit on clock speed on AVRs.
 
The following users thanked this post: Raj

Offline RajTopic starter

  • Frequent Contributor
  • **
  • Posts: 702
  • Country: in
  • Self taught, experimenter, noob(ish)
Re: Stuck in a loop, atmega8 i2c ...
« Reply #2 on: December 17, 2016, 02:16:36 pm »
atmega8a on 8mhz clock
Get an AVR with debugging circuitry, stop punishing yourself.
And AFAIK there is a bottom limit on clock speed on AVRs.

advice 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 mhz

anyway...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
 

Offline Brutte

  • Frequent Contributor
  • **
  • Posts: 614
Re: Stuck in a loop, atmega8 i2c ...
« Reply #3 on: December 17, 2016, 02:51:01 pm »
Quote
Get an AVR with debugging circuitry, stop punishing yourself.
And AFAIK there is a bottom limit on clock speed on AVRs.

advice taken....there's an arduino is on the way to my house right away.
Arduino 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: [Select]
<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.
 
The following users thanked this post: Raj

Online Ian.M

  • Super Contributor
  • ***
  • Posts: 13377
Re: Stuck in a loop, atmega8 i2c ...
« Reply #4 on: December 17, 2016, 03:13:15 pm »
Even the Arduino hardware has to be hacked to make it debugable + you need a debugger supported by AVR Studio.  See http://www.hilltop-cottage.info/blogs/adam/debugging-arduino-using-debugwire-atmel-studio-and-an-avr-dragon/
 
The following users thanked this post: Raj

Offline RajTopic starter

  • Frequent Contributor
  • **
  • Posts: 702
  • Country: in
  • Self taught, experimenter, noob(ish)
Re: Stuck in a loop, atmega8 i2c ...
« Reply #5 on: December 17, 2016, 03:32:09 pm »
Thanks for the help...ill try reading the error codes

and thanks for the link to the arduino hack
 

Offline Brutte

  • Frequent Contributor
  • **
  • Posts: 614
Re: Stuck in a loop, atmega8 i2c ...
« Reply #6 on: December 17, 2016, 03:35:03 pm »
Even the Arduino hardware has to be hacked to make it debugable
Ok, 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.
 
The following users thanked this post: Raj

Offline bktemp

  • Super Contributor
  • ***
  • Posts: 1616
  • Country: de
Re: Stuck in a loop, atmega8 i2c ...
« Reply #7 on: December 17, 2016, 03:56:02 pm »
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.
 
The following users thanked this post: Raj

Offline Kalvin

  • Super Contributor
  • ***
  • Posts: 2145
  • Country: fi
  • Embedded SW/HW.
Re: Stuck in a loop, atmega8 i2c ...
« Reply #8 on: December 17, 2016, 04:09:43 pm »
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.
 
The following users thanked this post: Raj

Offline RajTopic starter

  • Frequent Contributor
  • **
  • Posts: 702
  • Country: in
  • Self taught, experimenter, noob(ish)
Re: Stuck in a loop, atmega8 i2c ...
« Reply #9 on: December 17, 2016, 04:32:25 pm »
void i2c_writer(unsigned char data)
{
   uint16_t i2c_timeout_counter = 0;
   TWDR=data;
   TWCR=0b10000100;
   while ((!(TWCR & 0x80)) && (i2c_timeout_counter < 20000))
   {
      PORTB=0xFF;
      i2c_timeout_counter++;
   }
   if (i2c_timeout_counter >= 20000)
   {
      PORTC=0x07;
      PORTB=TWSR>>3;
   }
}


Wow, that took away a lot of work,thanks!
« Last Edit: December 17, 2016, 04:48:06 pm by Raj »
 

Offline TiN

  • Super Contributor
  • ***
  • Posts: 4543
  • Country: ua
    • xDevs.com
Re: Stuck in a loop, atmega8 i2c ...
« Reply #10 on: December 17, 2016, 05:44:09 pm »
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.
YouTube | Metrology IRC Chat room | Let's share T&M documentation? Upload! No upload limits for firmwares, photos, files.
 
The following users thanked this post: Raj

Offline Brutte

  • Frequent Contributor
  • **
  • Posts: 614
Re: Stuck in a loop, atmega8 i2c ...
« Reply #11 on: December 17, 2016, 08:24:54 pm »
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?

 
 
The following users thanked this post: Raj

Offline RajTopic starter

  • Frequent Contributor
  • **
  • Posts: 702
  • Country: in
  • Self taught, experimenter, noob(ish)
Re: Stuck in a loop, atmega8 i2c ...
« Reply #12 on: December 18, 2016, 05:51:36 am »
ok here's the error code i receive with above code....its the same if i remove the ds1307 from circuit entirely

In portB,the output becomes 01001,indicating the tws value is 01001000
ie-
     SLA+R transmitted with NACK received as per the guide presented by Brutte

So i guess i'll have to order a new RTC


btw the pull up resistors were 10k later changed to 4.7k
 

Offline RajTopic starter

  • Frequent Contributor
  • **
  • Posts: 702
  • Country: in
  • Self taught, experimenter, noob(ish)
Re: Stuck in a loop, atmega8 i2c ...
« Reply #13 on: December 18, 2016, 07:58:03 am »
wait a second..that isn't right... the clock lines go low and remains low after the transmission of slave address is complete
This happens even when the rtc is not connected
Btw...the rtc ic is not an original ds1307 but a ripoff/copy ie vs1307
« Last Edit: December 18, 2016, 08:30:45 am by Raj »
 

Offline bktemp

  • Super Contributor
  • ***
  • Posts: 1616
  • Country: de
Re: Stuck in a loop, atmega8 i2c ...
« Reply #14 on: December 18, 2016, 09:18:00 am »
wait a second..that isn't right... the clock lines go low and remains low after the transmission of slave address is complete
That 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:
Quote
Repeated START will be transmitted
STOP condition will be transmitted and TWSTO Flag will be reset
STOP condition followed by a START condition will be transmitted and TWSTO Flag will be reset
The 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.
 
The following users thanked this post: Raj

Offline RajTopic starter

  • Frequent Contributor
  • **
  • Posts: 702
  • Country: in
  • Self taught, experimenter, noob(ish)
Re: Stuck in a loop, atmega8 i2c ...
« Reply #15 on: December 18, 2016, 09:51:36 am »
wait a second..that isn't right... the clock lines go low and remains low after the transmission of slave address is complete
This happens even when the rtc is not connected
Btw...the rtc ic is not an original ds1307 but a ripoff/copy ie vs1307

funny thing is,

i2c_init();
   i2c_start();
   i2c_write(0x0D);  <==== this is where it gets stuck
   i2c_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 follows
Quote
TWDR=data;
   TWCR=0b10000100;
   while (!(TWCR & 0x80)){
      PORTB=TWSR>>3;}


and main to



Quote
i2c_init();
   i2c_start();
   PORTC=0b00001110;
   i2c_write(0x0D);
   PORTC=0b00001101;
   i2c_write(0);
   PORTC=0b00001011;
   i2c_write(0);
   PORTC=0b00000111;
   i2c_write(0);
   PORTC=0b00001100;
   i2c_write(0);
   PORTC=0b00001001;
   i2c_stop();
   PORTC=0x00000011;

the output of portb and c becomes as follows-
portb=0x01001 ie tws =01001000
ie-
     SLA+R transmitted with NACK received as per the guide presented by Brutte
port c=00001101 when it enters infinite loop
Maybe I should take a break until I get my arduino thus the ability to serially output the states of various registers
« Last Edit: December 18, 2016, 10:17:06 am by Raj »
 

Offline RajTopic starter

  • Frequent Contributor
  • **
  • Posts: 702
  • Country: in
  • Self taught, experimenter, noob(ish)
Re: Stuck in a loop, atmega8 i2c ...
« Reply #16 on: December 23, 2016, 07:56:13 am »
 ;D |O :-DD

Changed the rtc and it works fine after a little tweaking....the old rtc chips somehow died in storage. don't know why :-// :palm:
 

Offline stfsux

  • Contributor
  • Posts: 23
  • Country: 00
Re: Stuck in a loop, atmega8 i2c ...
« Reply #17 on: December 25, 2016, 12:32:11 pm »
Raj against the RTC
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf