xref: /qemu/hw/avr/atmega.c (revision 06b40d250ecfa1633209c2e431a7a38acfd03a98)
1 /*
2  * QEMU ATmega MCU
3  *
4  * Copyright (c) 2019-2020 Philippe Mathieu-Daudé
5  *
6  * This work is licensed under the terms of the GNU GPLv2 or later.
7  * See the COPYING file in the top-level directory.
8  * SPDX-License-Identifier: GPL-2.0-or-later
9  */
10 
11 #include "qemu/osdep.h"
12 #include "qemu/module.h"
13 #include "qemu/units.h"
14 #include "qapi/error.h"
15 #include "exec/target_page.h"
16 #include "system/memory.h"
17 #include "system/address-spaces.h"
18 #include "system/system.h"
19 #include "hw/qdev-properties.h"
20 #include "hw/sysbus.h"
21 #include "qom/object.h"
22 #include "hw/misc/unimp.h"
23 #include "migration/vmstate.h"
24 #include "atmega.h"
25 
26 enum AtmegaPeripheral {
27     POWER0, POWER1,
28     GPIOA, GPIOB, GPIOC, GPIOD, GPIOE, GPIOF,
29     GPIOG, GPIOH, GPIOI, GPIOJ, GPIOK, GPIOL,
30     USART0, USART1, USART2, USART3,
31     TIMER0, TIMER1, TIMER2, TIMER3, TIMER4, TIMER5,
32     PERIFMAX
33 };
34 
35 #define GPIO(n)     (n + GPIOA)
36 #define USART(n)    (n + USART0)
37 #define TIMER(n)    (n + TIMER0)
38 #define POWER(n)    (n + POWER0)
39 
40 typedef struct {
41     uint16_t addr;
42     enum AtmegaPeripheral power_index;
43     uint8_t power_bit;
44     /* timer specific */
45     uint16_t intmask_addr;
46     uint16_t intflag_addr;
47     bool is_timer16;
48 } peripheral_cfg;
49 
50 struct AtmegaMcuClass {
51     /*< private >*/
52     SysBusDeviceClass parent_class;
53     /*< public >*/
54     const char *uc_name;
55     const char *cpu_type;
56     size_t flash_size;
57     size_t eeprom_size;
58     size_t sram_size;
59     size_t io_size;
60     size_t gpio_count;
61     size_t adc_count;
62     const uint8_t *irq;
63     const peripheral_cfg *dev;
64 };
65 typedef struct AtmegaMcuClass AtmegaMcuClass;
66 
67 DECLARE_CLASS_CHECKERS(AtmegaMcuClass, ATMEGA_MCU,
68                        TYPE_ATMEGA_MCU)
69 
70 static const peripheral_cfg dev168_328[PERIFMAX] = {
71     [USART0]        = {  0xc0, POWER0, 1 },
72     [TIMER2]        = {  0xb0, POWER0, 6, 0x70, 0x37, false },
73     [TIMER1]        = {  0x80, POWER0, 3, 0x6f, 0x36, true },
74     [POWER0]        = {  0x64 },
75     [TIMER0]        = {  0x44, POWER0, 5, 0x6e, 0x35, false },
76     [GPIOD]         = {  0x29 },
77     [GPIOC]         = {  0x26 },
78     [GPIOB]         = {  0x23 },
79 }, dev1280_2560[PERIFMAX] = {
80     [USART3]        = { 0x130, POWER1, 2 },
81     [TIMER5]        = { 0x120, POWER1, 5, 0x73, 0x3a, true },
82     [GPIOL]         = { 0x109 },
83     [GPIOK]         = { 0x106 },
84     [GPIOJ]         = { 0x103 },
85     [GPIOH]         = { 0x100 },
86     [USART2]        = {  0xd0, POWER1, 1 },
87     [USART1]        = {  0xc8, POWER1, 0 },
88     [USART0]        = {  0xc0, POWER0, 1 },
89     [TIMER2]        = {  0xb0, POWER0, 6, 0x70, 0x37, false }, /* TODO async */
90     [TIMER4]        = {  0xa0, POWER1, 4, 0x72, 0x39, true },
91     [TIMER3]        = {  0x90, POWER1, 3, 0x71, 0x38, true },
92     [TIMER1]        = {  0x80, POWER0, 3, 0x6f, 0x36, true },
93     [POWER1]        = {  0x65 },
94     [POWER0]        = {  0x64 },
95     [TIMER0]        = {  0x44, POWER0, 5, 0x6e, 0x35, false },
96     [GPIOG]         = {  0x32 },
97     [GPIOF]         = {  0x2f },
98     [GPIOE]         = {  0x2c },
99     [GPIOD]         = {  0x29 },
100     [GPIOC]         = {  0x26 },
101     [GPIOB]         = {  0x23 },
102     [GPIOA]         = {  0x20 },
103 };
104 
105 enum AtmegaIrq {
106     USART0_RXC_IRQ, USART0_DRE_IRQ, USART0_TXC_IRQ,
107     USART1_RXC_IRQ, USART1_DRE_IRQ, USART1_TXC_IRQ,
108     USART2_RXC_IRQ, USART2_DRE_IRQ, USART2_TXC_IRQ,
109     USART3_RXC_IRQ, USART3_DRE_IRQ, USART3_TXC_IRQ,
110     TIMER0_CAPT_IRQ, TIMER0_COMPA_IRQ, TIMER0_COMPB_IRQ,
111         TIMER0_COMPC_IRQ, TIMER0_OVF_IRQ,
112     TIMER1_CAPT_IRQ, TIMER1_COMPA_IRQ, TIMER1_COMPB_IRQ,
113         TIMER1_COMPC_IRQ, TIMER1_OVF_IRQ,
114     TIMER2_CAPT_IRQ, TIMER2_COMPA_IRQ, TIMER2_COMPB_IRQ,
115         TIMER2_COMPC_IRQ, TIMER2_OVF_IRQ,
116     TIMER3_CAPT_IRQ, TIMER3_COMPA_IRQ, TIMER3_COMPB_IRQ,
117         TIMER3_COMPC_IRQ, TIMER3_OVF_IRQ,
118     TIMER4_CAPT_IRQ, TIMER4_COMPA_IRQ, TIMER4_COMPB_IRQ,
119         TIMER4_COMPC_IRQ, TIMER4_OVF_IRQ,
120     TIMER5_CAPT_IRQ, TIMER5_COMPA_IRQ, TIMER5_COMPB_IRQ,
121         TIMER5_COMPC_IRQ, TIMER5_OVF_IRQ,
122     IRQ_COUNT
123 };
124 
125 #define USART_IRQ_COUNT     3
126 #define USART_RXC_IRQ(n)    (n * USART_IRQ_COUNT + USART0_RXC_IRQ)
127 #define USART_DRE_IRQ(n)    (n * USART_IRQ_COUNT + USART0_DRE_IRQ)
128 #define USART_TXC_IRQ(n)    (n * USART_IRQ_COUNT + USART0_TXC_IRQ)
129 #define TIMER_IRQ_COUNT     5
130 #define TIMER_CAPT_IRQ(n)   (n * TIMER_IRQ_COUNT + TIMER0_CAPT_IRQ)
131 #define TIMER_COMPA_IRQ(n)  (n * TIMER_IRQ_COUNT + TIMER0_COMPA_IRQ)
132 #define TIMER_COMPB_IRQ(n)  (n * TIMER_IRQ_COUNT + TIMER0_COMPB_IRQ)
133 #define TIMER_COMPC_IRQ(n)  (n * TIMER_IRQ_COUNT + TIMER0_COMPC_IRQ)
134 #define TIMER_OVF_IRQ(n)    (n * TIMER_IRQ_COUNT + TIMER0_OVF_IRQ)
135 
136 static const uint8_t irq168_328[IRQ_COUNT] = {
137     [TIMER2_COMPA_IRQ]      = 8,
138     [TIMER2_COMPB_IRQ]      = 9,
139     [TIMER2_OVF_IRQ]        = 10,
140     [TIMER1_CAPT_IRQ]       = 11,
141     [TIMER1_COMPA_IRQ]      = 12,
142     [TIMER1_COMPB_IRQ]      = 13,
143     [TIMER1_OVF_IRQ]        = 14,
144     [TIMER0_COMPA_IRQ]      = 15,
145     [TIMER0_COMPB_IRQ]      = 16,
146     [TIMER0_OVF_IRQ]        = 17,
147     [USART0_RXC_IRQ]        = 19,
148     [USART0_DRE_IRQ]        = 20,
149     [USART0_TXC_IRQ]        = 21,
150 }, irq1280_2560[IRQ_COUNT] = {
151     [TIMER2_COMPA_IRQ]      = 14,
152     [TIMER2_COMPB_IRQ]      = 15,
153     [TIMER2_OVF_IRQ]        = 16,
154     [TIMER1_CAPT_IRQ]       = 17,
155     [TIMER1_COMPA_IRQ]      = 18,
156     [TIMER1_COMPB_IRQ]      = 19,
157     [TIMER1_COMPC_IRQ]      = 20,
158     [TIMER1_OVF_IRQ]        = 21,
159     [TIMER0_COMPA_IRQ]      = 22,
160     [TIMER0_COMPB_IRQ]      = 23,
161     [TIMER0_OVF_IRQ]        = 24,
162     [USART0_RXC_IRQ]        = 26,
163     [USART0_DRE_IRQ]        = 27,
164     [USART0_TXC_IRQ]        = 28,
165     [TIMER3_CAPT_IRQ]       = 32,
166     [TIMER3_COMPA_IRQ]      = 33,
167     [TIMER3_COMPB_IRQ]      = 34,
168     [TIMER3_COMPC_IRQ]      = 35,
169     [TIMER3_OVF_IRQ]        = 36,
170     [USART1_RXC_IRQ]        = 37,
171     [USART1_DRE_IRQ]        = 38,
172     [USART1_TXC_IRQ]        = 39,
173     [TIMER4_CAPT_IRQ]       = 42,
174     [TIMER4_COMPA_IRQ]      = 43,
175     [TIMER4_COMPB_IRQ]      = 44,
176     [TIMER4_COMPC_IRQ]      = 45,
177     [TIMER4_OVF_IRQ]        = 46,
178     [TIMER5_CAPT_IRQ]       = 47,
179     [TIMER5_COMPA_IRQ]      = 48,
180     [TIMER5_COMPB_IRQ]      = 49,
181     [TIMER5_COMPC_IRQ]      = 50,
182     [TIMER5_OVF_IRQ]        = 51,
183     [USART2_RXC_IRQ]        = 52,
184     [USART2_DRE_IRQ]        = 53,
185     [USART2_TXC_IRQ]        = 54,
186     [USART3_RXC_IRQ]        = 55,
187     [USART3_DRE_IRQ]        = 56,
188     [USART3_TXC_IRQ]        = 57,
189 };
190 
connect_peripheral_irq(const AtmegaMcuClass * k,SysBusDevice * dev,int dev_irqn,DeviceState * cpu,unsigned peripheral_index)191 static void connect_peripheral_irq(const AtmegaMcuClass *k,
192                                    SysBusDevice *dev, int dev_irqn,
193                                    DeviceState *cpu,
194                                    unsigned peripheral_index)
195 {
196     int cpu_irq = k->irq[peripheral_index];
197 
198     if (!cpu_irq) {
199         return;
200     }
201     /* FIXME move that to avr_cpu_set_int() once 'sample' board is removed */
202     assert(cpu_irq >= 2);
203     cpu_irq -= 2;
204 
205     sysbus_connect_irq(dev, dev_irqn, qdev_get_gpio_in(cpu, cpu_irq));
206 }
207 
connect_power_reduction_gpio(AtmegaMcuState * s,const AtmegaMcuClass * k,DeviceState * cpu,unsigned peripheral_index)208 static void connect_power_reduction_gpio(AtmegaMcuState *s,
209                                          const AtmegaMcuClass *k,
210                                          DeviceState *cpu,
211                                          unsigned peripheral_index)
212 {
213     unsigned power_index = k->dev[peripheral_index].power_index;
214     assert(k->dev[power_index].addr);
215     sysbus_connect_irq(SYS_BUS_DEVICE(&s->pwr[power_index - POWER0]),
216                        k->dev[peripheral_index].power_bit,
217                        qdev_get_gpio_in(cpu, 0));
218 }
219 
atmega_realize(DeviceState * dev,Error ** errp)220 static void atmega_realize(DeviceState *dev, Error **errp)
221 {
222     AtmegaMcuState *s = ATMEGA_MCU(dev);
223     const AtmegaMcuClass *mc = ATMEGA_MCU_GET_CLASS(dev);
224     DeviceState *cpudev;
225     SysBusDevice *sbd;
226     char *devname;
227     size_t i;
228 
229     if (!s->xtal_freq_hz) {
230         error_setg(errp, "\"xtal-frequency-hz\" property must be provided.");
231         return;
232     }
233 
234     /* CPU */
235     object_initialize_child(OBJECT(dev), "cpu", &s->cpu, mc->cpu_type);
236 
237     object_property_set_uint(OBJECT(&s->cpu), "init-sp",
238                              mc->io_size + mc->sram_size - 1, &error_abort);
239 
240     qdev_realize(DEVICE(&s->cpu), NULL, &error_abort);
241     cpudev = DEVICE(&s->cpu);
242 
243     /*
244      * SRAM
245      *
246      * Softmmu is not able mix i/o and ram on the same page.
247      * Therefore in all cases, the first page exclusively contains i/o.
248      *
249      * If the MCU's i/o region matches the page size, then we can simply
250      * allocate all ram starting at the second page.  Otherwise, we must
251      * allocate some ram as i/o to complete the first page.
252      */
253     assert(mc->io_size == 0x100 || mc->io_size == 0x200);
254     if (mc->io_size >= TARGET_PAGE_SIZE) {
255         memory_region_init_ram(&s->sram, OBJECT(dev), "sram", mc->sram_size,
256                                &error_abort);
257         memory_region_add_subregion(get_system_memory(),
258                                     OFFSET_DATA + mc->io_size, &s->sram);
259     } else {
260         int sram_io_size = TARGET_PAGE_SIZE - mc->io_size;
261         void *sram_io_mem = g_malloc0(sram_io_size);
262 
263         memory_region_init_ram_device_ptr(&s->sram_io, OBJECT(dev), "sram-as-io",
264                                           sram_io_size, sram_io_mem);
265         memory_region_add_subregion(get_system_memory(),
266                                     OFFSET_DATA + mc->io_size, &s->sram_io);
267         vmstate_register_ram(&s->sram_io, dev);
268 
269         memory_region_init_ram(&s->sram, OBJECT(dev), "sram",
270                                mc->sram_size - sram_io_size, &error_abort);
271         memory_region_add_subregion(get_system_memory(),
272                                     OFFSET_DATA + TARGET_PAGE_SIZE, &s->sram);
273     }
274 
275     /* Flash */
276     memory_region_init_rom(&s->flash, OBJECT(dev),
277                            "flash", mc->flash_size, &error_fatal);
278     memory_region_add_subregion(get_system_memory(), OFFSET_CODE, &s->flash);
279 
280     /*
281      * I/O
282      *
283      * 0x00 - 0x1f: Registers
284      * 0x20 - 0x5f: I/O memory
285      * 0x60 - 0xff: Extended I/O
286      */
287     s->io = qdev_new(TYPE_UNIMPLEMENTED_DEVICE);
288     qdev_prop_set_string(s->io, "name", "I/O");
289     qdev_prop_set_uint64(s->io, "size", mc->io_size);
290     sysbus_realize_and_unref(SYS_BUS_DEVICE(s->io), &error_fatal);
291     sysbus_mmio_map_overlap(SYS_BUS_DEVICE(s->io), 0, OFFSET_DATA, -1234);
292 
293     /* Power Reduction */
294     for (i = 0; i < POWER_MAX; i++) {
295         int idx = POWER(i);
296         if (!mc->dev[idx].addr) {
297             continue;
298         }
299         devname = g_strdup_printf("power%zu", i);
300         object_initialize_child(OBJECT(dev), devname, &s->pwr[i],
301                                 TYPE_AVR_MASK);
302         sysbus_realize(SYS_BUS_DEVICE(&s->pwr[i]), &error_abort);
303         sysbus_mmio_map(SYS_BUS_DEVICE(&s->pwr[i]), 0,
304                         OFFSET_DATA + mc->dev[idx].addr);
305         g_free(devname);
306     }
307 
308     /* GPIO */
309     for (i = 0; i < GPIO_MAX; i++) {
310         int idx = GPIO(i);
311         if (!mc->dev[idx].addr) {
312             continue;
313         }
314         devname = g_strdup_printf("atmega-gpio-%c", 'a' + (char)i);
315         create_unimplemented_device(devname,
316                                     OFFSET_DATA + mc->dev[idx].addr, 3);
317         g_free(devname);
318     }
319 
320     /* USART */
321     for (i = 0; i < USART_MAX; i++) {
322         int idx = USART(i);
323         if (!mc->dev[idx].addr) {
324             continue;
325         }
326         devname = g_strdup_printf("usart%zu", i);
327         object_initialize_child(OBJECT(dev), devname, &s->usart[i],
328                                 TYPE_AVR_USART);
329         qdev_prop_set_chr(DEVICE(&s->usart[i]), "chardev", serial_hd(i));
330         sbd = SYS_BUS_DEVICE(&s->usart[i]);
331         sysbus_realize(sbd, &error_abort);
332         sysbus_mmio_map(sbd, 0, OFFSET_DATA + mc->dev[USART(i)].addr);
333         connect_peripheral_irq(mc, sbd, 0, cpudev, USART_RXC_IRQ(i));
334         connect_peripheral_irq(mc, sbd, 1, cpudev, USART_DRE_IRQ(i));
335         connect_peripheral_irq(mc, sbd, 2, cpudev, USART_TXC_IRQ(i));
336         connect_power_reduction_gpio(s, mc, DEVICE(&s->usart[i]), idx);
337         g_free(devname);
338     }
339 
340     /* Timer */
341     for (i = 0; i < TIMER_MAX; i++) {
342         int idx = TIMER(i);
343         if (!mc->dev[idx].addr) {
344             continue;
345         }
346         if (!mc->dev[idx].is_timer16) {
347             create_unimplemented_device("avr-timer8",
348                                         OFFSET_DATA + mc->dev[idx].addr, 5);
349             create_unimplemented_device("avr-timer8-intmask",
350                                         OFFSET_DATA
351                                         + mc->dev[idx].intmask_addr, 1);
352             create_unimplemented_device("avr-timer8-intflag",
353                                         OFFSET_DATA
354                                         + mc->dev[idx].intflag_addr, 1);
355             continue;
356         }
357         devname = g_strdup_printf("timer%zu", i);
358         object_initialize_child(OBJECT(dev), devname, &s->timer[i],
359                                 TYPE_AVR_TIMER16);
360         object_property_set_uint(OBJECT(&s->timer[i]), "cpu-frequency-hz",
361                                  s->xtal_freq_hz, &error_abort);
362         sbd = SYS_BUS_DEVICE(&s->timer[i]);
363         sysbus_realize(sbd, &error_abort);
364         sysbus_mmio_map(sbd, 0, OFFSET_DATA + mc->dev[idx].addr);
365         sysbus_mmio_map(sbd, 1, OFFSET_DATA + mc->dev[idx].intmask_addr);
366         sysbus_mmio_map(sbd, 2, OFFSET_DATA + mc->dev[idx].intflag_addr);
367         connect_peripheral_irq(mc, sbd, 0, cpudev, TIMER_CAPT_IRQ(i));
368         connect_peripheral_irq(mc, sbd, 1, cpudev, TIMER_COMPA_IRQ(i));
369         connect_peripheral_irq(mc, sbd, 2, cpudev, TIMER_COMPB_IRQ(i));
370         connect_peripheral_irq(mc, sbd, 3, cpudev, TIMER_COMPC_IRQ(i));
371         connect_peripheral_irq(mc, sbd, 4, cpudev, TIMER_OVF_IRQ(i));
372         connect_power_reduction_gpio(s, mc, DEVICE(&s->timer[i]), idx);
373         g_free(devname);
374     }
375 
376     create_unimplemented_device("avr-twi",          OFFSET_DATA + 0x0b8, 6);
377     create_unimplemented_device("avr-adc",          OFFSET_DATA + 0x078, 8);
378     create_unimplemented_device("avr-ext-mem-ctrl", OFFSET_DATA + 0x074, 2);
379     create_unimplemented_device("avr-watchdog",     OFFSET_DATA + 0x060, 1);
380     create_unimplemented_device("avr-spi",          OFFSET_DATA + 0x04c, 3);
381     create_unimplemented_device("avr-eeprom",       OFFSET_DATA + 0x03f, 3);
382 }
383 
384 static const Property atmega_props[] = {
385     DEFINE_PROP_UINT64("xtal-frequency-hz", AtmegaMcuState,
386                        xtal_freq_hz, 0),
387 };
388 
atmega_class_init(ObjectClass * oc,const void * data)389 static void atmega_class_init(ObjectClass *oc, const void *data)
390 {
391     DeviceClass *dc = DEVICE_CLASS(oc);
392 
393     dc->realize = atmega_realize;
394     device_class_set_props(dc, atmega_props);
395     /* Reason: Mapped at fixed location on the system bus */
396     dc->user_creatable = false;
397 }
398 
atmega168_class_init(ObjectClass * oc,const void * data)399 static void atmega168_class_init(ObjectClass *oc, const void *data)
400 {
401     AtmegaMcuClass *amc = ATMEGA_MCU_CLASS(oc);
402 
403     amc->cpu_type = AVR_CPU_TYPE_NAME("avr5");
404     amc->flash_size = 16 * KiB;
405     amc->eeprom_size = 512;
406     amc->sram_size = 1 * KiB;
407     amc->io_size = 256;
408     amc->gpio_count = 23;
409     amc->adc_count = 6;
410     amc->irq = irq168_328;
411     amc->dev = dev168_328;
412 };
413 
atmega328_class_init(ObjectClass * oc,const void * data)414 static void atmega328_class_init(ObjectClass *oc, const void *data)
415 {
416     AtmegaMcuClass *amc = ATMEGA_MCU_CLASS(oc);
417 
418     amc->cpu_type = AVR_CPU_TYPE_NAME("avr5");
419     amc->flash_size = 32 * KiB;
420     amc->eeprom_size = 1 * KiB;
421     amc->sram_size = 2 * KiB;
422     amc->io_size = 256;
423     amc->gpio_count = 23;
424     amc->adc_count = 6;
425     amc->irq = irq168_328;
426     amc->dev = dev168_328;
427 };
428 
atmega1280_class_init(ObjectClass * oc,const void * data)429 static void atmega1280_class_init(ObjectClass *oc, const void *data)
430 {
431     AtmegaMcuClass *amc = ATMEGA_MCU_CLASS(oc);
432 
433     amc->cpu_type = AVR_CPU_TYPE_NAME("avr51");
434     amc->flash_size = 128 * KiB;
435     amc->eeprom_size = 4 * KiB;
436     amc->sram_size = 8 * KiB;
437     amc->io_size = 512;
438     amc->gpio_count = 86;
439     amc->adc_count = 16;
440     amc->irq = irq1280_2560;
441     amc->dev = dev1280_2560;
442 };
443 
atmega2560_class_init(ObjectClass * oc,const void * data)444 static void atmega2560_class_init(ObjectClass *oc, const void *data)
445 {
446     AtmegaMcuClass *amc = ATMEGA_MCU_CLASS(oc);
447 
448     amc->cpu_type = AVR_CPU_TYPE_NAME("avr6");
449     amc->flash_size = 256 * KiB;
450     amc->eeprom_size = 4 * KiB;
451     amc->sram_size = 8 * KiB;
452     amc->io_size = 512;
453     amc->gpio_count = 54;
454     amc->adc_count = 16;
455     amc->irq = irq1280_2560;
456     amc->dev = dev1280_2560;
457 };
458 
459 static const TypeInfo atmega_mcu_types[] = {
460     {
461         .name           = TYPE_ATMEGA168_MCU,
462         .parent         = TYPE_ATMEGA_MCU,
463         .class_init     = atmega168_class_init,
464     }, {
465         .name           = TYPE_ATMEGA328_MCU,
466         .parent         = TYPE_ATMEGA_MCU,
467         .class_init     = atmega328_class_init,
468     }, {
469         .name           = TYPE_ATMEGA1280_MCU,
470         .parent         = TYPE_ATMEGA_MCU,
471         .class_init     = atmega1280_class_init,
472     }, {
473         .name           = TYPE_ATMEGA2560_MCU,
474         .parent         = TYPE_ATMEGA_MCU,
475         .class_init     = atmega2560_class_init,
476     }, {
477         .name           = TYPE_ATMEGA_MCU,
478         .parent         = TYPE_SYS_BUS_DEVICE,
479         .instance_size  = sizeof(AtmegaMcuState),
480         .class_size     = sizeof(AtmegaMcuClass),
481         .class_init     = atmega_class_init,
482         .abstract       = true,
483     }
484 };
485 
486 DEFINE_TYPES(atmega_mcu_types)
487