-
Notifications
You must be signed in to change notification settings - Fork 17
Differences for the XMega implementation
There are a few API changes that had to be made to support the XMega processors.
For the XMega, the attachInterrupt function is now defined as follows:
void attachInterrupt(uint8_t interruptNum, void (*)(void), int mode);
For C++ code, the 'mode' parameter gets a default value of 0.
Typical usage:
attachInterrupt(PORTD_INT0, // the specific interrupt vector - see pins_arduino.h
my_callback, // user-defined callback function
RISING // interrupt mode (can be LOW, HIGH, RISING, FALLING, CHANGE)
| INT_MODE_PIN_DEFAULT // the pin(s) to assign to this interrupt, or default pin 2
| INT_MODE_PRI_DEFAULT); // interrupt priority, default is 'high' (optional)
The 'interruptNum' constants are in pins_arduino.h, typically defined similar to:
#define PORTD_INT0 0
#define PORTD_INT1 1
#define PORTC_INT0 2
#define PORTC_INT1 3
#define PORTE_INT0 4
#define PORTE_INT1 5
#define PORTA_INT0 6
#define PORTA_INT1 7
#define PORTB_INT0 8
#define PORTB_INT1 9
#define PORTR_INT0 10
#define PORTR_INT1 11
The constant 'EXTERNAL_NUM_INTERRUPTS' will equal the total number of available interrupts. Note that these constants vary from processor to processor. The E5 series only has 'INT0' interrupts, for example, and the A1(U) series has additional ports and interrupts.
The 'mode' parameter uses the following constants from 'Arduino.h':
#define INT_MODE_PRI_DEFAULT 0
#define INT_MODE_PRI_LOW 0x0040
#define INT_MODE_PRI_MED 0x0080
#define INT_MODE_PRI_HIGH 0x00c0
#define INT_MODE_PIN0 0x0100
#define INT_MODE_PIN1 0x0200
#define INT_MODE_PIN2 0x0400
#define INT_MODE_PIN3 0x0800
#define INT_MODE_PIN4 0x1000
#define INT_MODE_PIN5 0x2000
#define INT_MODE_PIN6 0x4000
#define INT_MODE_PIN7 0x8000
#define INT_MODE_PIN_DEFAULT 0
Multiple pins can be specified for interrupts. These are 'or'd with the following trigger types:
#define LOW 0x0
#define HIGH 0x1
#define CHANGE 2
#define FALLING 3
#define RISING 4
The 'readCalibrationData' function returns store calibration data. It is XMega-specific and necessary for features like the A:D converter.
The function is defined as:
uint8_t readCalibrationData(uint16_t iIndex);
where 'iIndex' is the index within the 'calibration data' that was stored during manufacturing.
Typical 'iIndex' values can be found in the appropriate avr 'io' header file. These need to be cast from 'const void *' to an unsigned short integer, as follows:
readCalibrationData((uint16_t)&PRODSIGNATURES_ADCACAL0);
For the ATXMega32E5, the 'product signatures' are defined as follows (from iox32e5.h):
/* NVM_PROD_SIGNATURES - Production Signatures */
#define PRODSIGNATURES_RCOSC8M _SFR_MEM8(0x0000)
#define PRODSIGNATURES_RCOSC32K _SFR_MEM8(0x0002)
#define PRODSIGNATURES_RCOSC32M _SFR_MEM8(0x0003)
#define PRODSIGNATURES_RCOSC32MA _SFR_MEM8(0x0004)
#define PRODSIGNATURES_LOTNUM0 _SFR_MEM8(0x0008)
#define PRODSIGNATURES_LOTNUM1 _SFR_MEM8(0x0009)
#define PRODSIGNATURES_LOTNUM2 _SFR_MEM8(0x000A)
#define PRODSIGNATURES_LOTNUM3 _SFR_MEM8(0x000B)
#define PRODSIGNATURES_LOTNUM4 _SFR_MEM8(0x000C)
#define PRODSIGNATURES_LOTNUM5 _SFR_MEM8(0x000D)
#define PRODSIGNATURES_WAFNUM _SFR_MEM8(0x0010)
#define PRODSIGNATURES_COORDX0 _SFR_MEM8(0x0012)
#define PRODSIGNATURES_COORDX1 _SFR_MEM8(0x0013)
#define PRODSIGNATURES_COORDY0 _SFR_MEM8(0x0014)
#define PRODSIGNATURES_COORDY1 _SFR_MEM8(0x0015)
#define PRODSIGNATURES_ADCACAL0 _SFR_MEM8(0x0020)
#define PRODSIGNATURES_ADCACAL1 _SFR_MEM8(0x0021)
#define PRODSIGNATURES_ACACURRCAL _SFR_MEM8(0x0028)
#define PRODSIGNATURES_TEMPSENSE0 _SFR_MEM8(0x002E)
#define PRODSIGNATURES_TEMPSENSE1 _SFR_MEM8(0x002F)
#define PRODSIGNATURES_DACA0OFFCAL _SFR_MEM8(0x0030)
#define PRODSIGNATURES_DACA0GAINCAL _SFR_MEM8(0x0031)
#define PRODSIGNATURES_DACA1OFFCAL _SFR_MEM8(0x0034)
#define PRODSIGNATURES_DACA1GAINCAL _SFR_MEM8(0x0035)
The 'wait_for_interrupt' function does what it says on the tin: It waits for an interrupt to occur, and after the ISR returns, it returns control to the calling function. This trick is performed by using one of the XMega's "sleep" modes, which can reduce overall current consumption.
It is implemented as:
void wait_for_interrupt(void);
The 'low_power_delay' function is identical to the built-in 'delay' function, except that it makes use of one of the XMega's "sleep" modes, which can reduce overall current consumption.
It is implented as:
void low_power_delay(unsigned long ms);
where 'ms' is the number of milliseconds to delay. Since the system timer creates interrupts, there should be no deviation in actual performance between using 'delay' or 'low_power_delay' (other than the reduction in current consumption).
© 2015-2019 (and later) by S.F.T. Inc.
You may freely use this documentation as you see fit, provided that appropriate credit is made, similar to a BSD or MIT license.