I2C routines in an ISR . . . Help

Go To Last Post
8 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Below are two non-interrupt I2C routines (AVR-libc) which work just fine a main while(1) loop. However, I want to obtain RTC data every second so that I can eventually test it in an ISR and if appropriate get my ADC started BEFORE leaving the ISR.

RTC_1Hz_INTERRUPT_HANDLER(SIG_INTERRUPT2)
{
   RTC_1Hz_Interrupt_flag = 1;

// reset register pointer of RTC
   i2cMasterSendNI(RTC_ADDR, 1, 0x00);
   
// get data
   i2cMasterReceiveNI(RTC_ADDR, 7, RTC_data);
}

But I just can't get them to work in the ISR. I understand that they do not require interrupts to be enabled, however I have tried putting a sei() and cli() pair around them to no effect.

Because RTC_data is a shared array I made it a volatile u08 array with global scope. When I made it a volatile array I needed to change the last parameter in the i2cMaster SendNI() and i2cMasterReceiveNI() functions to volatile to eliminate compiler error messages.

Hopefully this has nothing to do with using the previous version of WinAVR. Can anyone suggest what I am doing wrong?

Thanks

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Just out of interest can you confirm that your code includes:

#define RTC_1Hz_INTERRUPT_HANDLER SIGNAL

??

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes it does.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So are you configuring the INT2 pin to trigger this interrupt somewhere? Are you sure the electronics (a switch/button by any chance?) connected to INT2 is generating the correct trigger event? If it is a switch, what are you doing about debounce? Do you know for sure that it IS triggering on the condition you programmed for ? (often a good way to check is to have the ISR light an LED temporarily connected to a spare PORT pin)

BTW your first post seems a bit confused you mention the ADC but nothing in that code has anything to do with ADC.

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes. The DS1307 is connected to INT2 generating 1 second interrupts. A LED in the ISR confirms I am getting interrupts.

There is alot more code! I was hoping someone with AVR-libc I2C experience might have run across similar problems.

The example Pascal includes with his library works fine. Another "conclusion" I have come to is that you shouldn't mix the interrupt I2C versions with the non-interrupt ones, HOWEVER his example shows both :(

I will make up another test program that just toggles an LED in the ISR before and after calls to these functions to see if I can demonstrate the problem.

Thank you for your help thus far.

Cheers,
davef

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I was confused when you said it was avr-libc that was providing your I2C routines because the avr-libc I know (the runtime library for the avr-gcc compiler) doesn't contain I2C routines but your mention of "Pascal" presumably suggests that the lib you are uing is actually Pascal Stang's Procyon AVRlib ( http://hubbard.engr.scu.edu/avr/... )? That is NOT avr-libc!

I seem to remeber reading previous posts about the I2C in Pascal's library and the interaction with interrupts here so I'm sure a thread search ("I2C", "Procyon", "Stang", etc.) will probably turn up something for you.

Cliff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi, This might help.

When an intr occurs, the processor switch state. This can happen at any time. I don;t know if you are using the I2C interface anywhere else, but if you do, then you are using a resource that is shared. Without any locking mechanism you will run into trouble. As an intr can occur while you are busy using the i2c interface. If it is the case, either prevent intr;s to occur while using this resource, or try to do the following, which might be better design pratice.

Instead of reading the rtc in your intr. Set a flag. Poll this flag in your main loop. Once the flag is set, read the rtc, clr the flag and continue.. Remember that code within an intr should execute with the least amount of clock cycle used. You don't whan't an intr to block for a long time.

Hope this helps..

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sorry fellows, I do mean AVR-lib.

Josias, I wanted to be able to test the results of an I2C read of the RTC in the ISR to get a faster response time, rather then polling in the main loop. I am also using the I2C to read and write to an EEPROM, but not at the same time. Perhaps I need to think more carefully about this!

Cliff, I suspected some interaction so I tried using the NI versions. I thought these versions would not experience the problem both of you mention.

I asked this question a few weeks ago, because I was unsure of the differences between these two versions. I'll try some more searches.

Thanks to the both of you,
davef