A question on interrupts (Mega128)

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

I've programmed on a lot of other micro-controllers (starting with the 6502 and 6802) in various languages (asm, BASIC and C), but I don't do this professionally.

I'm using a mega128 board (the xTW board below) to translate X10 TW523 interface (TTL serial SYNC bit stream data) to Insteon (RS232 via an Insteon PLM or Insteon PLC). Technically I could do UPB, Z-Wave or any other Home Automation protocol also. So far I'm through the pin assignment and Pseudo code stage. I'm now writing code to test what I think something is supposed to do (like generate an interrupt every 120th of a second and toggle a gpio bit).

This is my first time dealing with an AVR so I have some learning to do (sort of the main point of choosing the AVR). The reason for the Mega128 was the need for two serial ports and the 128K of flash may be necessary but still use an 8 bit processor.

I have a number of interrupts that I need to deal with. One is a timer to generate the 50/60 Hz zero crossing pulse to the TW523, another is a 1 ms timer for the uC Rx pulse to the TW523, another is the TW523 uC Tx pin (interrupt on change), EEPROM handling and finally there is the PLM RS232 receive interrupt. I've enclosed a high level function diagram:

        X10       Insteon      Insteon or
        Raw         API        X10 PLC Cmd
 -----+     +-----+     +-----+
    Zc|<----|     |---->|Rx   |
 uC Tx|---->| xTW |     | PLM |---< AC >
    Rx|<----|     |<----|Tx   |
 -----+     +-+-+-+     +-+-+-+
           ^   \ \_[gnd]_/ /   ^
           |    \__[12v]__/    |
           |                   |
           |       TW523       |
           \    Replacement    /
            ---------v---------
                    xTW 

In the end I may end up with more things that can cause interrupts but for now it's just this (I'm still working out those details).

My first concern is that I may not know what I'm asking for (I haven't given it my full thought yet). My main concern is interrupt priority and/or dealing with an interrupt while in another interrupt handler. At this moment I haven't given a priority to any interrupts but I have an idea of what I want. Is there some text, howto or posting that describe interrupt priority/interrupt-in-interrupt handling on the AVR? In the past my projects have not been so interrupt intensive.

My main loop will be dealing with the buffered data from the interrupts, translating from X10 to Insteon (or vise-versa) or preparing data (buffering) for output.

In the end this should end up as an article in Circuit Cellar magazine (if they accept it) and may be Open Source software (the Insteon portion of the code may be an issue).

Neil Cherry
Linux Home Automation
Author: Linux Smart Homes For Dummies.

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

Looks like a cool project. My 'gut feel' based on using avrs for a couple of years is that 120 hz ints are no prob for any avr at some speed, say 4mhz, and if it is a prob, just speed it up to 8 or 16 or 20mhz. Brute force. There arent any reassignable interrupt priorities though.... keep the handlers as small as possible. AVR hw stack saves sp, and a sw stack saves params. Some avr compilers maintain two stacks, gcc keeps everything in one, and rtos for avr depend heavily on stack model. I'd say, start with a mega128 dev board and no rtos and see how far you get. Man, these two replies couldnt be more general could they? -----v

Imagecraft compiler user

Last Edited: Sun. Dec 30, 2007 - 06:38 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ncherry wrote:
My first concern is that I may not know what I'm asking for (I haven't given it my full thought yet). My main concern is interrupt priority and/or dealing with an interrupt while in another interrupt handler.
Interrupt priority is describe in the ATMega128 (like all other AVRs) datasheet. From page 15 of ATMega128 datasheet:
Quote:
The complete list of vectors is shown in “Interrupts” on page 59.
The list also determines the priority levels of the different interrupts. The lower the
address the higher is the priority level.

As for enabling interrupts during an ISR, you can certainly do that. Different C compilers (assuming you're using C) handle that a bit differently. Whether you want interrupts enabled during an ISR is application dependent. In many cases you do not, in some cases you do.

Edit: if you do some web searches for SEI and interrupt service routine, you'll likely find some discussion about the risks and benefits of reenabling interrupts during an ISR. One of the main problems with enabling interrupts during an ISR is that if your interrupts stack deeply, you may run out of stack space. Another potential issue is the ISR that keeps getting activated during its own execution (like an INT0 level interrupt) so you go into an infinite loop. Overall message: reenable interrupts during an ISR with great care.

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

kmr wrote:
ncherry wrote:
My first concern is that I may not know what I'm asking for (I haven't given it my full thought yet). My main concern is interrupt priority and/or dealing with an interrupt while in another interrupt handler.
Interrupt priority is describe in the ATMega128 (like all other AVRs) datasheet. From page 15 of ATMega128 datasheet:
Quote:
The complete list of vectors is shown in “Interrupts” on page 59.
The list also determines the priority levels of the different interrupts. The lower the
address the higher is the priority level.

DOH! :oops: Make me look in the most obvious place! Sorry about that. I did a quick look at the datasheet (opened in a PDF viewer with my shell and emacs) and didn't see that. I saw that section and only recalled the first part. I'll sit down and read that properly. Thanks.
Quote:

As for enabling interrupts during an ISR, you can certainly do that. Different C compilers (assuming you're using C) handle that a bit differently. Whether you want interrupts enabled during an ISR is application dependent. In many cases you do not, in some cases you do.

Edit: if you do some web searches for SEI and interrupt service routine, you'll likely find some discussion about the risks and benefits of reenabling interrupts during an ISR. One of the main problems with enabling interrupts during an ISR is that if your interrupts stack deeply, you may run out of stack space. Another potential issue is the ISR that keeps getting activated during its own execution (like an INT0 level interrupt) so you go into an infinite loop. Overall message: reenable interrupts during an ISR with great care.


That's great! I'll search for the sei after I read through the data sheet. I don't expect to see much interrupt-in-interrupt devouring the stack as the only free running interrupt is the RS232 receive. Everything else triggers off the zero crossing (Zc) timer. When I jump into the Zc interrupt handler I'll set a few things, turn on a few interrupts (the other timer and the pin change interrupt) and get out of there real quick. The RS232 can happen at any time but it only needs to grab the byte out of the Receive port and toss it into the buffer (115K). The transmit is not interrupt driven (polled). I'll need to sit down and figure out how often the interrupts can occur.

TW523 Interface
              ___     _
Zc  <------ _|   |___|  = 60 or 50 Hz pulse train (Timer interrupt)
              _
Tx  ------> _| |_____   = 1 ms pulse (Incoming Edge interrupt)
              _
Rx  <------ _| |_____   = 1 ms pulse (Timer interrupt)

The Zc is the trigger for the Tx or Rx. If the Tx or the Rx occurs at the during each other it's a collision and both devices need to back off. I haven't figured out how I'll deal with that.

Here's some more details abut my setup. I'm using GCC 4.1.0, the code is written in C (but delving into assembly language won't be a problem if I need to). I have the Atmel JTAGICE MKII and an ISP that work under Linux. I'm currently using avrdude to program the mega128 (ISP). I just got info on the MKII power requirements so I can start putting that to good use. The mega128 is running at 16MHz. I don't know if there will be a 'final product' but if there is I'll minimize as much as possible to reduce cost. This is a prototype and one off costs are not a concern as much as getting it working.

Thanks for the info!

Neil Cherry
Linux Home Automation
Author: Linux Smart Homes For Dummies.

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

bobgardner wrote:
Looks like a cool project. My 'gut feel' based on using avrs for a couple of years is that 120 hz ints are no prob for any avr at some speed, say 4mhz, and if it is a prob, just speed it up to 8 or 16 or 20mhz. Brute force. There arent any reassignable interrupt priorities though.... keep the handlers as small as possible. AVR hw stack saves sp, and a sw stack saves params. Some avr compilers maintain two stacks, gcc keeps everything in one, and rtos for avr depend heavily on stack model. I'd say, start with a mega128 dev board and no rtos and see how far you get. Man, these two replies couldnt be more general could they? -----v
General but still useful.

An RTOS is probably over kill for this project. I don't think there is enough going on to need a proper OS. I just need to make sure that I don't loose any serial bytes, TTL bits or miss the dead line for the zero crossing (Zc) crossing.

Right now I'm trying to figure out how accurate I have to be with the Zc to satisfy the micro-controller. I'll probably throw on a 32KHz xtal to satisfy those timing requirements. My other concern is how much fudge factor I have on emulating the Zc. From Zc to data out I have about 50 uS to make the bit change. Of course the micro-controller doesn't know I'm not talking to a real AC line so latency is not a huge issue just as long as the Zc change takes place every 1/120 sec and the data pulse occurs no later than 50 uS. I could just set the data bit (if there is any data) and toggle the Zc bit at the same time. No timing issue then. I've got a whole 1 mS to sense the data in and I usually do that from 400 to 600 uS (did this for a PIC project).

Neil Cherry
Linux Home Automation
Author: Linux Smart Homes For Dummies.

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

ncherry wrote:
the only free running interrupt is the RS232 receive. Everything else triggers off the zero crossing (Zc) timer. When I jump into the Zc interrupt handler I'll set a few things, turn on a few interrupts (the other timer and the pin change interrupt) and get out of there real quick. The RS232 can happen at any time but it only needs to grab the byte out of the Receive port and toss it into the buffer (115K). The transmit is not interrupt driven (polled). I'll need to sit down and figure out how often the interrupts can occur.
Getting out of your ISR quickly is always a good idea. As for how often USART RX interrupts can occur, assuming your receiving 8N1, you have 10 bits per byte at 115.2bits/sec, or 87uS per byte. Running at 16MHz, that's 1389 cycles per USART byte.

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

kmr wrote:
ncherry wrote:
the only free running interrupt is the RS232 receive. Everything else triggers off the zero crossing (Zc) timer. When I jump into the Zc interrupt handler I'll set a few things, turn on a few interrupts (the other timer and the pin change interrupt) and get out of there real quick. The RS232 can happen at any time but it only needs to grab the byte out of the Receive port and toss it into the buffer (115K). The transmit is not interrupt driven (polled). I'll need to sit down and figure out how often the interrupts can occur.
Getting out of your ISR quickly is always a good idea. As for how often USART RX interrupts can occur, assuming your receiving 8N1, you have 10 bits per byte at 115.2bits/sec, or 87uS per byte. Running at 16MHz, that's 1389 cycles per USART byte.

Wow that sounds great, sounds like I have a decent amount of time to get things done. Of course this is before I've decided what I'll be doing between those interrupts. :wink:

I'll have to be careful what I do in the ISR and get out quick. Now to actually write the code.

Thanks

Neil Cherry
Linux Home Automation
Author: Linux Smart Homes For Dummies.

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

Neil, I have some code available for quickly storing a USART RX byte in an ISR in the Serial_Lcd code that I posted in https://www.avrfreaks.net/index.p...

Click the download button and look in the serial_lcd.c file. The code looks somewhat complex because of being compatible on IAR, ICC, and GCC as well as the ISR as conditional code to implement a Clear to Send signal.