External interrupt for ZX24u
-
- Posts: 2
- Joined: 28 January 2016, 7:13 AM
External interrupt for ZX24u
I am working with a ZX24u using the xmega128A4U. I would like to create an external interrupt to wake the controller up. Looks like Pin 6 can be setup for this, but I'm having trouble understanding how to set up the interrupt in the software. No problem putting the controller to sleep.
You may be able to use WaitForInterrupt() but you'd have to have that call in a separate task from the one that enters sleep mode. It may be simpler to write your own code to enable a pin change interrupt and write the interrupt handler for it. Any I/O pin can be used for the pin change interrupt and such interrupts will awaken the device in all sleep modes.
To write this specialized code you'll need the xmega datasheets. You can get the datasheets specific to the A4U device from the Atmel website. However, the primary difference between the A4 and the A4U is the presence of the USB controllers in the latter so you should be able to get the information you need from the xmega A4 datasheets available via links at the bottom of the Downloads Page.
To write this specialized code you'll need the xmega datasheets. You can get the datasheets specific to the A4U device from the Atmel website. However, the primary difference between the A4 and the A4U is the presence of the USB controllers in the latter so you should be able to get the information you need from the xmega A4 datasheets available via links at the bottom of the Downloads Page.
- Don Kinzer
The sample code below configures an xmega device to generate an interrupt on a state change of a pin. The code is written specifically for pin C.0 but it can be modified for any pin of any port by following the instructions. It uses port interrupt 0 but it could be modified to use port interrupt 1 if necessary.
Code: Select all
Const PORT_INT0IF_bm as Byte = &H01 ' interrupt flag
Const PORT_INT0LVL_gm as Byte = &H03 ' priority mask
Const PORT_INT0LVL as Byte = &H02 ' medium priority
Const PORT_ISC_gm as Byte = &H07 ' input sense mask
Const PORT_ISC_val as Byte = &H00 ' either edge
Dim Volatile pinChange as Boolean
Sub Main()
Call initPinChangeInt()
Do
If (pinChange) Then
Debug.Print "got pin change"
pinChange = False
End If
Loop
End Sub
'
'' initPinChangeInt
'
' This subroutine sets up a pin for a pin change interrupt on either edge. The code
' is written specifically for pin C.0. To modify it for a pin on a different port, change
' the occurrences of PORTC to PORTA, PORTD, etc. Further, the value written to the INTOMASK
' register must be modified to reflect the bit of the port and the PIN0CTRL must be changed
' to match the bit number as well. For example, to change to B.7, PORTC must be changed to
' PORTB, the value assigned to Register.PORTB_INT0MASK must be changed to &H80 and
' Register.PORTC_PIN0CTRL must be changed to Register.PORTB_PIN7CTRL.
'
Sub initPinChangeInt()
' set the pin for level change interrupt
Register.PORTC_PIN0CTRL = (Register.PORTC_PIN0CTRL And Not PORT_ISC_gm) Or PORT_ISC_val
' clear any pending interrupt
Register.PORTC_INTFLAGS = PORT_INT0IF_bm
' prepare for the pin change interrupt
Register.PORTC_INT0MASK = &H01 ' change the value to reflect the port pin
Register.PORTC_INTCTRL = (Register.PORTC_INTCTRL And Not PORT_INT0LVL_gm) Or PORT_INT0LVL
End Sub
'
' This is the ISR for the pin change interrupt. For purposes of this example, a flag is set
' to indicate that the interrupt occurred.
'
ISR PORTC_INT0()
pinChange = True
End ISR
- Don Kinzer
I neglected to mention that the flag in the pin change ISR is only needed for the test driver implemented in Main(). For the use case of awakening from sleep an empty ISR would work fine but even then, the flag indicating the occurrence of the interrupt might be useful.
Further, you can change the trigger condition of the pin change interrupt by changing the value of the PORT_ISC_val constant.
Further, you can change the trigger condition of the pin change interrupt by changing the value of the PORT_ISC_val constant.
- Don Kinzer