[EA28 Pin Mapping](EA28.png "Arduino Pin Mapping for AVR EA28")
Image not available - absent help we do not foresee being able to provide any sort of pinout diagram for this or future parts
- | AVRxxEA28 |
---|---|
Flash Memory | 8192, 16384, 32768, or 65536 |
Flash Memory (With Optiboot) | 7680, 15872, 32212, or 65024 |
SRAM | 1024, 2048, 4096, 6144 |
EEPROM | 512 |
User Row | 64 |
Max. Frequency (rated, MHz) | 20 |
Clock Sources | INT, EXT, XTAL |
Packages Available | SOIC, SSOP, PDIP, VQFN (4x4mm 0.4p) |
Total pins on package | 28 |
I/O Pins (not reset/UPDI) | 22 |
Fully async pins | 24 |
UPDI as I/O Pin | Yes |
PWM capable I/O pins | 28 |
Max simultaneous PWM outputs | 13 |
16-bit Type A Timers - pins ea | 2: 18 / 6 |
16-bit Type B Timers, (pins) | 4: 4 |
12-bit Type D pins | None - no TCD |
USART (pin mappings) | 3: 5 / 3 / 2 |
SPI (pin mappings) | 1: 6 |
TWI/I2C (pin mappings) | 1: 3 |
12-bit dif ADC w/PGA input pins | 20 |
Of those, neg. diff. inputs | 20 |
10-bit DAC | 1 |
Analog Comparator (AC) | 2 |
Zero-Cross Detectors (ZCD) | None |
Custom Logic Blocks (LUTs) | 4 : |
Event System channels (out pins) | 6 : 7 |
MVIO, pins | None |
Flash Endurance | 1k-10k see errata |
LED_BUILTIN (and optiboot led) | PIN_PA7 |
The EA28s have only one thing going for them aside from the fact that there's a DIP package, and that is that the VQFN28 4mm x 4mm package is available. If it offers the same economics as the DD28 in that package, it will be popular with institutional customers. These are also notable for cutting deep towards tinyAVR territory, with flash size options as low as 8k.
- Has the new true differential ADC with 1-16x PGA and all the goodies that come with that.
- EVSYS has gotten some improvements - each port gets to choose two pins, and the PIT two intervals, and then ANY event channel can use it. How it always should have been!
- There is 4k of NRWW flash and the rest is RWW. But it got errata'ed hard, so it might as well not be RWW.
- We got a bad deal on CLKCTRL. Not only did we get tinyAVR's 16/20 oscillator... We got the crapola calibration of the Dx-series. Pfft.
All pins on the EA-series are "fully async" and can respond to events shorter than 1 clock cycle, and can wake the chip on RISING or FALLING edges, not just LOW_LEVEL and CHANGE.
USART0 retains the portmux emporium he gained with the DD-series. 5 mux options!
All | TX | RX | XDIR | XCK |
---|---|---|---|---|
DEFAULT | PA0 | PA1 | PA2 | PA3 |
ALT1 | PA4 | PA5 | PA6 | PA7 |
ALT2 | PA2 | PA3 | - | - |
ALT3 | PD4 | PD5 | PD6 | PD7 |
ALT4 | PC1 | PC2 | PC3 | - |
NONE | - | - | - | - |
Likewise, USART1 retains the new mapping it got. Obviously ALT1 is not an option because it would be on PC4-PC7, which don't exist on 32 pin parts.
All | TX | RX | XDIR | XCK |
---|---|---|---|---|
DEFAULT | PC0 | PC1 | PC2 | PC3 |
ALT2 | PD6 | PD7 | - | - |
NONE | - | - | - | - |
Not much in the way of options here huh? At least they let it keep the USART!
All | TX | RX | XDIR | XCK |
---|---|---|---|---|
DEFAULT | PF0 | PF1 | ||
NONE | - | - | - | - |
SPI0, who hit the jackpot in the DD series has held onto his wealth of portmux options, is back with the same options as the DDs had (see The SPI.h library documentation for details). No Alt1 or Alt2 options on 32-pin parts. Alt1 is PORTE, and Alt2 is PORTG.
SPI | MOSI | MISO | SCK | SS |
---|---|---|---|---|
SPI0 DEFAULT | PA4 | PA5 | PA6 | PA7 |
SPI0 ALT3 | PA0 | PA1 | PC0 | PC1 |
SPI0 ALT4 | PD4 | PD5 | PD6 | PD7 |
SPI0 ALT5 | PC0 | PC1 | PC2 | PC3 |
SPI0 ALT6 | PC1 | PC2 | PC3 | PF7 |
NONE | - | - | - | - |
TWI0 missed out on most of the DD Portmux Punch, but still managed to gain a single mux option then and hold onto it. As always ALT1 is not available on 32-pin parts because it is strictly worse than the default.
Mapping | swap | Master or Slave | Dual Mode Slave |
---|---|---|---|
DEFAULT | 0 | SDA/PA2 SCL/PA3 | SDA/PC2 SCL/PC3 |
ALT2 | 2 | SDA/PC2 SCL/PC3 | |
ALT3 | 3 | SDA/PA0 SCL/PA1 | SDA/PC2 SCL/PC3 |
There's no TCD, but with two TCA's and 4 TCBs to back them up, you've still got a respectable 16 maximum independent outputs. TCA1 gained a few new mux options, but only 3-pin ones, and there's no 6-pin mapping available for it.
The Type A timers (TCA0 and TCA1) can be mapped to different pins as a group only, and analogWrite() is PORTMUX-aware - you can set TCA0 to output on any port's pin 0-5, and TCA1 in 3 channel mode to port A or D. Using this feature is easy - but not quite as trivial as other parts, since there are two bitfields. You simply write to the portmux register PORTMUX.TCAROUTEA = (TCA1 pinset) | (TCA0 pinset)
and then analogWrite() normally. TCA0 pinset is the port number (0-5 for ports A-F). The pinsets values for TCA1 are shown below (equivalent to (4, or 5) << 3).
We default to PORTD, as PORTA has lots of peripherals competing for the lower pins. To maximize available PWM pins, we would choose either TCA0 on PORTA and TCA1 on PORTD or the other way around, and PORTA's lower half is more useful than that of PORTD - though neither is ideal! As noted above and described below, it can be freely changed at runtime!
TCA0 | WO0 | WO1 | WO2 | WO3 | WO4 | WO5 | Pinset |
---|---|---|---|---|---|---|---|
PORTA | PA0 | PA1 | PA2 | PA3 | PA4 | PA5 | 0x00 |
PORTC | PC0 | PC1 | PC2 | PC3 | - | - | 0x02 |
PORTD | PD0 | PD1 | PD2 | PD3 | PD4 | PD5 | 0x03 |
PORTF | PF0 | PF1 | - | - | - | - | 0x05 |
TCA1 | WO0 | WO1 | WO2 | WO3 | WO4 | WO5 | Pinset |
---|---|---|---|---|---|---|---|
PORTA | PA4 | PA5 | PA6 | - | - | - | 0x20 |
PORTD | PD5 | PD5 | PD6 | - | - | - | 0x28 |
// Simple Assignment:
PORTMUX.TCAROUTEA = PORTMUX_TCA0_PORTD_gc | PORTMUX_TCA1_PORTA_gc; // PWM on PORTF and PORTB pins 0-5
// one-liner, set TCA0 PORTD (not as readily generalizable):
PORTMUX.TCAROUTEA = (PORTMUX.TCAROUTEA & PORTMUX_TCA1_gm) | PORTMUX_TCA0_PORTC_gc; // Move TCA0 PWM to PORTD but don't change TCA1 PWM
// The first option is slightly faster, as it isn't a read-modify-write. You almost always want TCA1 mux to be set to PORTB.
// Note that PORTMUX_TCA0_PORTA_gc and PORTMUX_TCA1_PORTB_gc have a numeric value of 0. So for the common case, you can use simple assignment to set
// PORTMUX.TCAROUTEA to PA, PB, PC, PD, PE, or PF
// Maximally generalizable method (for any multi-bit bitfield w/in a a register):
uint8_t tcaroutea = PORTMUX.TCAROUTEA; // Registers are volatile variables, so load it to temporary variable to change it in multiple steps
tcaroutea &= ~PORTMUX_TCA0_gm; // mask off the bits we will change. This method (copy to local var, &= ~THIS_BITFIELD_gm, |= THIS_GROUPCODE_gc ) generalizes better
tcaroutea |= PORTMUX_TCA0_PORTx_gc; // and then set them to their new value.
PORTMUX.TCAROUTEA = tcaroutea; //since the then write the temp variable back to the register.
// The above constructions will both give 7 clocks and 6 words and the compiler output identical - lds, andi, ori, sts (while the simple assignment would optimize down to only 3 words, 3 clocks (ldi, sts)).
// In contrast, the naive method:
PORTMUX.TCAROUTEA &= ~PORTMUX_TCA0_gm;
PORTMUX.TCAROUTEA |= PORTMUX_TCA0_PORTx_gc;
// takes 12 clocks/10 words - t has to load the value, modify, and store it, and then reload it, make the second modification, and store it again.
These are NOT PORTMUX-aware. Only the bold pin can be used without modifying or creating a new variant file. But since 28-pin parts don't have any of the alternate pins, I don't imagine this is a concern.
The type B timers are much better utility timers than PWM timers. TCB2 is the default millis timer and cannot be used for PWM in that mode.
TCBn | Default | Alt |
---|---|---|
TCB0 | PA2 | |
TCB1 | PA3 | |
TCB2 | PC0 | |
TCB3 | PC1 |
Following precedent set by MegaCoreX, we declare that pin 7 - PIN_PA7
shall be the pin that the core "expects" to be connected to an LED. LED_BUILTIN is defined as that pin, and the bootloader will set that pin as output and try to blink the LED. Note that if the bootloader is not used, and your sketch does not reference LED_BUILTIN
this pin is not otherwise treated any differently. This can be overridden if a custom board definition is created by passing -DLED_BUILTIN = (some other pin)
in the build.extra_flags
field.
Reset (PF6) can be set to work as an input (but never an output). The UPDI pin (PF7) can be used as an I/O pin. but in this case HV UPDI is needed to reprogram.
ALL PINS can be used as positive or negative side of a differential measurement. On accumulated readings, there is a sign chopping option to reduce offset error. See The analog guide for more information.
When all else fails, read the real documentation. They keep moving the .pdf files around, so now I just link to the product page, from whence the datasheet, errata, and "technical briefs".
Datasheets and errata change. You can sign up to get emails about such changes through the Microchip PCN system; if you don't, be sure to always use the latest version of the datasheet and especially the errata
At a minimum, everyone using a modern AVR should plan on having a PDF viewer open with the datasheet, and a text editor with a good search function and the ioavr______.h file open so that when you're trying to use a constant, but the compiler says it isn't declared/defined, you can search the io header for a key phrase in the constant and figure out how it was spelled/formatted or copy/paste it to your sketch. (see the IO headers for more information and links to them. I also keep the AVR instruction set manual open in the PDF viewer as well as the silicon errata and datasheet clarification. Datasheet clarifications are a bigger deal than an erratum, usually. An erratum says "Okay, this doesn't work, but it will some day, maybe" while a datasheet clarification says "This would be an errata, but we're not even going to pretend that we'll fix it some day". But watch out - datasheet clarifications vanish from the list once the datasheet has been updated!
The "Technical Briefs" are somewheat inconsistent in their value, but some are quite good. Still waiting on one about how to get the best out of the ADC - they seem allergic to making quantitative recommendations.