-
Notifications
You must be signed in to change notification settings - Fork 17
3. API Changes for XMega
A few APIs have changed, out of necessity, to support the XMega.
#nbsp; pin is the I/O pin number, 0 through 'n'
mode is the pin mode
example: INPUT, OUTPUT, INPUT_PULLUP, etc.
In the original Arduino IDE, the pinMode() function could only assign INPUT, OUTPUT, or INPUT_PULLUP. To facilitate the enhanced modes of the XMega I/O pins, you can assign one of the following for 'mode':
INPUT - totem pole, input (no pull up/down)
OUTPUT - totem pole, output
INPUT_BUS_KEEPER - weak pull up/down to maintain state when switched to or in input mode
INPUT_PULLUP - pull up resistor on input
INPUT_PULLDOWN - pull down resistor on input
OUTPUT_OR - output open 'P' drain/collector, no pull down
OUTPUT_AND - output open 'N' drain/collector, no pull up
INPUT_OR_PULLDOWN - input with open 'P' drain/collector and pulldown
INPUT_AND_PULLUP - input with open 'N' drain/collector and pullup
OUTPUT_OR_PULLDOWN - output with open 'P' drain/collector and pulldown
OUTPUT_AND_PULLUP - output with open 'N' drain/collector and pullup
The following 'or' masks can be applied to 'mode' to change the 'sense' behavior. this is particularly important for interrupt pins, and can also affect how input pins behave. For normal I/O pin assignment, use 'INPUT_SENSE_DEFAULT'. For analog inputs, use 'INPUT_SENSE_DISABLED'.
INPUT_SENSE_DEFAULT - input sense default - currently 'BOTH'
INPUT_SENSE_RISING - rising level change
INPUT_SENSE_FALLING - falling level change
INPUT_SENSE_BOTH - both rising AND falling level change - needed for normal INPUT
INPUT_SENSE_LEVEL - high level (or low if 'inverted' I/O)
INPUT_SENSE_DISABLED - buffered input disabled (use for analog inputs only)
INPUT_OUTPUT_INVERT - set this bit for 'inverted' I/O
NOTE: 'inverted' I/O is 're-inverted' by digitalRead and digitalWrite for consistency. The effect of the 'INVERT' bit is particularly important for LEVEL sense.
port is the I/O port and int number
example: PORTC_INT0, PORTD_INT0, PORTR_INT1, etc.
callback is a pointer to a user callback function
mode (new) is a bit-flag indicating the following:
trigger mode - LOW, HIGH, RISING, FALLING, CHANGE
interrupt pin - INT_MODE_PIN_DEFAULT, INT_MODE_PIN0, etc.
priority - INT_MODE_PRI_DEFAULT, INT_MODE_PRI_HIGH, etc.
typical usage:
attachInterrupt(PORTD_INT0,
my_callback,
RISING
| INT_MODE_PIN_DEFAULT
| INT_MODE_PRI_DEFAULT);
The port (formerly 'interrupt number') is passed to 'detachInterrupt' and detaches ALL interrupts for that particular port and interrupt combination. Some CPUs have 2 interrupts per port, some only one. The first will be labeled 'INT0', and subsequent interrupts 'INT1', etc. Each port+interrupt combination can only have a single callback, so you should assign the callback and all of the interrupt pins at the same time. It will be up to the callback functino to determine which pins is responsible for the interrupt.
There is a small exception with hardware flow control, which manages its interrupts separately, in conjuction with 'attachInterrupt()' and 'detachInterrupt()' calls. It is possible to assign an interrupt on the same port as the hardware flow control pins, without interfering. However, its priority will not be lowered from 'HIGH'.
iIndex is the index within the 'calibration data' to be read
This function reads the 'calibration data', which is assigned by the manufacturer to contain the calibration data necessary for certain functions. This also includes CPU identification information that can be used to uniquely identify the processor. One practical use is found in setting up the A:D converter, by reading the calibration data and assigning it to the 'CAL' register for the A:D converter during setup.
This function should be called whenever you exit from 'sleep' mode to re-assign the correct values to the A:D converter. On the XMega, sleep mode pretty much clears the slate for all peripherals. Serial ports and other peripherals are automatically initialized by 'Start' and similar member functions. But for the A:D converter, there was no official way to reset it. So this function was added.
typical usage:
// interrupt callback for 'wake-up'
void wake_up(void)
{
sleep_disable(); // must do this
detachInterrupt(PORTC_INT0);
}
...
// serial port shutdown
Serial.end();
Serial2.end();
set_sleep_mode(SLEEP_MODE_EXT_STANDBY);
// wake up with LOW level on PORTC pin 2
attachInterrupt(PORTC_INT0, wake_up, LOW);
// disable interrupts - see avr/sleep.h
cli();
power_all_disable();
sleep_enable(); // only if ints are off
// optionally disable BOD while sleeping
#ifdef sleep_bod_disable
sleep_bod_disable();
#endif
sei(); // enable interrupts
sleep_cpu();
// when I awake, I'll be here
sleep_disable(); // make sure
sei(); // ints on (make sure)
power_all_enable(); // see avr/power.h
...
adc_setup(); // re-init A:D
© 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.