Interrupts in 1280

Discussion specific to the ZX-1281 and ZX-1280 microcontrollers as well as the ZX-1281 and ZX-1280 Dev Boards.
Post Reply
angad
Posts: 9
Joined: 23 January 2009, 20:31 PM

Interrupts in 1280

Post by angad »

Hi,
I need to use hardware interrupts for zx 1280. I went through the documentation for enabling the interrupts in Atmega 1280 datasheet. I tried the following** code but the code did not run until commented out the EIMSK register statement.

Code: Select all

Sub Main()

Dim switch_input as Byte = 0
Main_loop:

  call putpin(D.0,0)
  call putpin(D.1,3)

  Register.EICRA = &H01 
  Register.EIMSK = &H01
  Register.SREG = &H80

  debug.print "the code runs "
End Sub

ISR INT0()
  for ijk = 1 to 10
   debug.print "Reached ISR"
  next ijk
End ISR
This code shows the debug statement in Main as long as I comment out the "Register.EIMSK = &H01" statement. It never enters the ISR, though I apply a corresponding trigger.

Kindly help me with this issue.

Also, I need to know as to what would happen if the H/W interrupt pin is open. That is, say if the interrupt is configured to trigger on logic 1, and the int pin on port D is open initially, would it trigger if I give logic 1 on open pin? Or do I have to ground the open pin when not in use?

Regards,
Angad.

[admin edit: added code tags]
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Re: Interrupts in 1280

Post by dkinzer »

angad wrote:Kindly help me with this issue.
There are a number issues with the code:
  • The INT0 input is being made an output by the first PutPin() call.
  • The assignment to Register.SREG is unnecessary since interrupts are enabled already when Main() begins executing.
  • An ISR should be as small as possible and do as little as possible. Generally speaking, it should never perform multi-character serial I/O or any other operation that may require the occurrence of an interrupt to complete since interrupts are disabled when in an ISR.
The code below illustrates how you can demonstrate that the INT0 ISR is working. Note, particularly, that you should not connect a mechanical switch directly to the INT0 input since they suffer from contact bounce and will probably generate multiple transitions on make and/or break. I tested this code using a debounced toggle switch. A schematic of the debounced switch circuit is shown in the attached image.

Code: Select all

Private int0Count as UnsignedInteger

Sub Main()
  Dim lastCount as UnsignedInteger = 0

  ' enable INT0 on any edge
  Register.EICRA = &H01
  Register.EIMSK = &H01
  Debug.Print "initialization completed"

  Do
    ' get the current interrupt count
    Dim count as UnsignedInteger
    Atomic
      count = int0Count
    End Atomic

    ' see if the interrupt count has changed
    If &#40;count <> lastCount&#41; Then
      Debug.Print "INT0 count is now "; count
      lastCount = count
    End If
  Loop
End Sub

ISR INT0&#40;&#41;
  int0Count = int0Count + 1
End ISR
Note the use of the Atomic block construct to protect the retrieval of the interrupt count. This is necessary since the count is a multi-byte value and an interrupt could occur between the retrieval of the constituent bytes possibly causing an invalid value to be read.
angad wrote:Also, I need to know as to what would happen if the H/W interrupt pin is open.
An I/O pin that is set to be an input with the pullup disabled and no connection will "float". That is to say that at any moment, the processor may interpret the level as a logic zero or a logic one. Essentially, the unconnected pin will act like an antenna and will be influenced by electromagnetic radiation in the vicinity. Clearly, this is an undesirable condition, one that can be avoided by adding a pullup or pull down resistor to ensure that the pin assumes a known state when not connected.

One other aspect that should be noted is that unconnected input pins with no pullup or pulldown resistor can cause higher than normal current consumption. When the floating input is between the thresholds for logic zero and logic one high currents flow in the input stages. Although such currents are not harmful to the device, if the device is powered by a battery it will discharge more quickly than it otherwise would. If you have a battery-powered application, all I/O pins should either be outputs or they should be inputs with something connected to them. Unused inputs should be grounded or have a pullup or pulldown resistor.
Attachments
Debounced switch
Debounced switch
debounce.jpg (11.42 KiB) Viewed 8023 times
- Don Kinzer
angad
Posts: 9
Joined: 23 January 2009, 20:31 PM

Post by angad »

Thank you for this update.

Your example looks good but I want the External ISR functionality itself to perform a few things before it exits out. Basically I am using serial port in my application which receives a set of 6 bytes and then distributes it to corresponding microcontrollers through the Zbasic I/O ports. Apart from this funtionality, my Zbasic application is supposed to track the emergency switch through the ext interrupt and accordingly update all the 6 controllers by sending a special string. The thing is 'getqueue' function waits until the specific number of bytes is available. While it waits for the data to be available, if emergency S/W is activated, I want the ISR to send a special string to corresponding controllers.

The example you provided uses a count for INT0 and checks for a condition in the main. I cannot do this as I am using getqueue. I tried my ISR with a debug in main and a different debug message in ISR. For some reason, when I provided the external interrupt trigger, the complete application hanged. It was neither displaying debug from main nor the debug from the ISR.

I could use the count condition demonstrated in your example (as ISR needs to be small) by using a timeout for getqueue. But I feel this is not an optimum solution.

I could give you my code, but I dont want to confuse you with the other functionalities in my code.


I need to know if debug used in ISR creates a problem.
dkinzer
Site Admin
Posts: 3120
Joined: 03 September 2005, 13:53 PM
Location: Portland, OR

Post by dkinzer »

angad wrote:Your example looks good but I want the External ISR functionality itself to perform a few things before it exits out.
The example was intended as a simple demonstration of the occurrence of an external event. It isn't particularly useful for anything else but it can be used as a starting point and can be incrementally refined to arrive at your intended destination.
angad wrote:The thing is 'getqueue' function waits until the specific number of bytes is available. While it waits for the data to be available, if emergency S/W is activated, I want the ISR to send a special string to corresponding controllers.
It is important to understand that you should not perform any activity in an ISR that has an arbitrarily long execution time, e.g. waiting for a given number of characters to appear in a queue. To reiterate, an ISR should be as short as possible. The ideal ISR just sets a flag and returns. Sometimes, you must resort to doing additional work but the objective should be to do absolutely as little as possible in the ISR.

In my earlier reply, I attempted to explain why you shouldn't attempt serial I/O (of any type, including Debug.Print) in an ISR. Apparently, I failed to make it clear. The crux of the problem is that for the duration of the execution of an ISR, interrupts are disabled. (As a side note, it is possible to re-enable interrupts but this is generally a "bad idea" for reasons that I won't go into at this time.) Consider, then, what can happen when you try to put data in the output queue for a serial port from within the ISR. If the queue is currently full, the PutQueue() call will sit in a loop waiting for space to become available. However, since interrupts are disabled, the serial I/O handler will never run and therefore space will never be available in the output queue. Your application will be hung, waiting forever.
angad wrote:I tried my ISR with a debug in main and a different debug message in ISR.
As explained above, you should not output debug messages from within an ISR.
angad wrote:For some reason, when I provided the external interrupt trigger, the complete application hanged.
Just as I described above that it might.
angad wrote:I could give you my code, but I dont want to confuse you with the other functionalities in my code.
You could, of course, produce a stripped down example of what you want to do. Once we see that we might have some suggestions for alternate implementation strategies.
- Don Kinzer
Post Reply