Reviewed-by: Michael Rolnik <mrol...@gmail.com>

On Sun, May 14, 2023 at 12:54 AM ~rmsyn <rm...@git.sr.ht> wrote:

> From: rmsyn <rmsync...@gmail.com>
>
> Adds support for ATmega16u4 and ATmega32u4 MCU definitions.
>
> Defines interrupts, memory layout, and machine types for generic
> ATmega16u4 and ATmega32u4 MCUs.
>
> Signed-off-by: rmsyn <rmsync...@gmail.com>
> ---
>  hw/avr/arduino.c |  36 ++++++++++++++
>  hw/avr/atmega.c  | 122 +++++++++++++++++++++++++++++++++++++++++++++++
>  hw/avr/atmega.h  |   2 +
>  3 files changed, 160 insertions(+)
>
> diff --git a/hw/avr/arduino.c b/hw/avr/arduino.c
> index 48ef478346..be04e412e6 100644
> --- a/hw/avr/arduino.c
> +++ b/hw/avr/arduino.c
> @@ -129,6 +129,34 @@ static void arduino_mega2560_class_init(ObjectClass
> *oc, void *data)
>      amc->xtal_hz    = 16 * 1000 * 1000; /* CSTCE16M0V53-R0 */
>  };
>
> +static void arduino_mega16u4_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    ArduinoMachineClass *amc = ARDUINO_MACHINE_CLASS(oc);
> +
> +    /*
> +     *
> https://ww1.microchip.com/downloads/en/devicedoc/atmel-7766-8-bit-avr-atmega16u4-32u4_datasheet.pdf
> +     */
> +    mc->desc        = "Arduino Mega 16u4 (ATmega16u4)";
> +    mc->alias       = "mega16u4";
> +    amc->mcu_type   = TYPE_ATMEGA16U4_MCU;
> +    amc->xtal_hz    = 16 * 1000 * 1000; /* CSTCE16M0V53-R0 */
> +};
> +
> +static void arduino_mega32u4_class_init(ObjectClass *oc, void *data)
> +{
> +    MachineClass *mc = MACHINE_CLASS(oc);
> +    ArduinoMachineClass *amc = ARDUINO_MACHINE_CLASS(oc);
> +
> +    /*
> +     *
> https://ww1.microchip.com/downloads/en/devicedoc/atmel-7766-8-bit-avr-atmega16u4-32u4_datasheet.pdf
> +     */
> +    mc->desc        = "Arduino Mega 32u4 (ATmega32u4)";
> +    mc->alias       = "mega32u4";
> +    amc->mcu_type   = TYPE_ATMEGA32U4_MCU;
> +    amc->xtal_hz    = 16 * 1000 * 1000; /* CSTCE16M0V53-R0 */
> +};
> +
>  static const TypeInfo arduino_machine_types[] = {
>      {
>          .name          = MACHINE_TYPE_NAME("arduino-duemilanove"),
> @@ -146,6 +174,14 @@ static const TypeInfo arduino_machine_types[] = {
>          .name          = MACHINE_TYPE_NAME("arduino-mega-2560-v3"),
>          .parent        = TYPE_ARDUINO_MACHINE,
>          .class_init    = arduino_mega2560_class_init,
> +    }, {
> +        .name          = MACHINE_TYPE_NAME("arduino-mega-16u4"),
> +        .parent        = TYPE_ARDUINO_MACHINE,
> +        .class_init    = arduino_mega16u4_class_init,
> +    }, {
> +        .name          = MACHINE_TYPE_NAME("arduino-mega-32u4"),
> +        .parent        = TYPE_ARDUINO_MACHINE,
> +        .class_init    = arduino_mega32u4_class_init,
>      }, {
>          .name           = TYPE_ARDUINO_MACHINE,
>          .parent         = TYPE_MACHINE,
> diff --git a/hw/avr/atmega.c b/hw/avr/atmega.c
> index a34803e642..292ad9a447 100644
> --- a/hw/avr/atmega.c
> +++ b/hw/avr/atmega.c
> @@ -27,6 +27,17 @@ enum AtmegaPeripheral {
>      GPIOG, GPIOH, GPIOI, GPIOJ, GPIOK, GPIOL,
>      USART0, USART1, USART2, USART3,
>      TIMER0, TIMER1, TIMER2, TIMER3, TIMER4, TIMER5,
> +    RESET,
> +    INT0, INT1, INT2, INT3, INT4, INT5, INT6,
> +    PCINT0,
> +    USB_GEN, USB_EP,
> +    WDT,
> +    SPI,
> +    ANALOG_COMP,
> +    ADC,
> +    EE_READY,
> +    TWI,
> +    SPM_READY,
>      PERIFMAX
>  };
>
> @@ -98,6 +109,30 @@ static const peripheral_cfg dev168_328[PERIFMAX] = {
>      [GPIOC]         = {  0x26 },
>      [GPIOB]         = {  0x23 },
>      [GPIOA]         = {  0x20 },
> +}, dev16u4_32u4[PERIFMAX] = {
> +    [POWER1]        = {  0x65 },
> +    [POWER0]        = {  0x64 },
> +    [TIMER4]        = {  0x4c, POWER1, 4, 0x72, 0x39, true },
> +    [SPM_READY]     = {  0x4a },
> +    [TWI]           = {  0x48 },
> +    [TIMER3]        = {  0x3e, POWER1, 3, 0x71, 0x38, true },
> +    [EE_READY]      = {  0x3c },
> +    [ADC]           = {  0x3a },
> +    [ANALOG_COMP]   = {  0x38 },
> +    [USART1]        = {  0x32, POWER1, 0 },
> +    [SPI]           = {  0x30 },
> +    [TIMER0]        = {  0x2a, POWER0, 5, 0x6e, 0x35, true },
> +    [TIMER1]        = {  0x20, POWER0, 3, 0x6f, 0x36, true },
> +    [WDT]           = {  0x18 },
> +    [USB_GEN]       = {  0x14 },
> +    [USB_EP]        = {  0x16 },
> +    [PCINT0]        = {  0x12 },
> +    [INT6]          = {  0x0e },
> +    [INT3]          = {  0x08 },
> +    [INT2]          = {  0x06 },
> +    [INT1]          = {  0x04 },
> +    [INT0]          = {  0x02 },
> +    [RESET]         = {  0x00 },
>  };
>
>  enum AtmegaIrq {
> @@ -117,6 +152,17 @@ enum AtmegaIrq {
>          TIMER4_COMPC_IRQ, TIMER4_OVF_IRQ,
>      TIMER5_CAPT_IRQ, TIMER5_COMPA_IRQ, TIMER5_COMPB_IRQ,
>          TIMER5_COMPC_IRQ, TIMER5_OVF_IRQ,
> +    RESET_IRQ,
> +    INT0_IRQ, INT1_IRQ, INT2_IRQ, INT3_IRQ, INT4_IRQ, INT5_IRQ, INT6_IRQ,
> +    PCINT0_IRQ,
> +    USB_GEN_IRQ, USB_EP_IRQ,
> +    WDT_IRQ,
> +    SPI_IRQ,
> +    ANALOG_COMP_IRQ,
> +    ADC_IRQ,
> +    EE_READY_IRQ,
> +    TWI_IRQ,
> +    SPM_READY_IRQ,
>      IRQ_COUNT
>  };
>
> @@ -184,6 +230,44 @@ static const uint8_t irq168_328[IRQ_COUNT] = {
>      [USART3_RXC_IRQ]        = 55,
>      [USART3_DRE_IRQ]        = 56,
>      [USART3_TXC_IRQ]        = 57,
> +}, irq16u4_32u4[IRQ_COUNT] = {
> +    [RESET_IRQ]             =  1,
> +    [INT0_IRQ]              =  2,
> +    [INT1_IRQ]              =  3,
> +    [INT2_IRQ]              =  4,
> +    [INT3_IRQ]              =  5,
> +    [INT6_IRQ]              =  8,
> +    [PCINT0_IRQ]            = 10,
> +    [USB_GEN_IRQ]           = 11,
> +    [USB_EP_IRQ]            = 12,
> +    [WDT_IRQ]               = 13,
> +    [TIMER1_CAPT_IRQ]       = 17,
> +    [TIMER1_COMPA_IRQ]      = 18,
> +    [TIMER1_COMPB_IRQ]      = 19,
> +    [TIMER1_COMPC_IRQ]      = 20,
> +    [TIMER1_OVF_IRQ]        = 21,
> +    [TIMER0_COMPA_IRQ]      = 22,
> +    [TIMER0_COMPB_IRQ]      = 23,
> +    [TIMER0_OVF_IRQ]        = 24,
> +    [SPI_IRQ]               = 25,
> +    [USART0_RXC_IRQ]        = 26,
> +    [USART0_DRE_IRQ]        = 27,
> +    [USART0_TXC_IRQ]        = 28,
> +    [ANALOG_COMP]           = 29,
> +    [ADC_IRQ]               = 30,
> +    [EE_READY_IRQ]          = 31,
> +    [TIMER3_CAPT_IRQ]       = 32,
> +    [TIMER3_COMPA_IRQ]      = 33,
> +    [TIMER3_COMPB_IRQ]      = 34,
> +    [TIMER3_COMPC_IRQ]      = 35,
> +    [TIMER3_OVF_IRQ]        = 36,
> +    [TWI_IRQ]               = 37,
> +    [SPM_READY_IRQ]         = 38,
> +    [TIMER4_COMPA_IRQ]      = 39,
> +    [TIMER4_COMPB_IRQ]      = 40,
> +    [TIMER4_COMPC_IRQ]      = 41,
> +    [TIMER4_OVF_IRQ]        = 42,
> +    /*[TIMER4_FPF_IRQ]        = 43,*/
>  };
>
>  static void connect_peripheral_irq(const AtmegaMcuClass *k,
> @@ -427,6 +511,36 @@ static void atmega2560_class_init(ObjectClass *oc,
> void *data)
>      amc->dev = dev1280_2560;
>  };
>
> +static void atmega16u4_class_init(ObjectClass *oc, void *data)
> +{
> +    AtmegaMcuClass *amc = ATMEGA_MCU_CLASS(oc);
> +
> +    amc->cpu_type = AVR_CPU_TYPE_NAME("avr5");
> +    amc->flash_size = 16 * KiB;
> +    amc->eeprom_size = 512;
> +    amc->sram_size = KiB + 256;
> +    amc->io_size = 64;
> +    amc->gpio_count = 32;
> +    amc->adc_count = 12;
> +    amc->irq = irq16u4_32u4;
> +    amc->dev = dev16u4_32u4;
> +};
> +
> +static void atmega32u4_class_init(ObjectClass *oc, void *data)
> +{
> +    AtmegaMcuClass *amc = ATMEGA_MCU_CLASS(oc);
> +
> +    amc->cpu_type = AVR_CPU_TYPE_NAME("avr5");
> +    amc->flash_size = 32 * KiB;
> +    amc->eeprom_size = KiB;
> +    amc->sram_size = 2 * KiB + 512;
> +    amc->io_size = 64;
> +    amc->gpio_count = 32;
> +    amc->adc_count = 12;
> +    amc->irq = irq16u4_32u4;
> +    amc->dev = dev16u4_32u4;
> +};
> +
>  static const TypeInfo atmega_mcu_types[] = {
>      {
>          .name           = TYPE_ATMEGA168_MCU,
> @@ -444,6 +558,14 @@ static const TypeInfo atmega_mcu_types[] = {
>          .name           = TYPE_ATMEGA2560_MCU,
>          .parent         = TYPE_ATMEGA_MCU,
>          .class_init     = atmega2560_class_init,
> +    }, {
> +        .name           = TYPE_ATMEGA16U4_MCU,
> +        .parent         = TYPE_ATMEGA_MCU,
> +        .class_init     = atmega16u4_class_init,
> +    }, {
> +        .name           = TYPE_ATMEGA32U4_MCU,
> +        .parent         = TYPE_ATMEGA_MCU,
> +        .class_init     = atmega32u4_class_init,
>      }, {
>          .name           = TYPE_ATMEGA_MCU,
>          .parent         = TYPE_SYS_BUS_DEVICE,
> diff --git a/hw/avr/atmega.h b/hw/avr/atmega.h
> index a99ee15c7e..37d36b9b69 100644
> --- a/hw/avr/atmega.h
> +++ b/hw/avr/atmega.h
> @@ -22,6 +22,8 @@
>  #define TYPE_ATMEGA328_MCU  "ATmega328"
>  #define TYPE_ATMEGA1280_MCU "ATmega1280"
>  #define TYPE_ATMEGA2560_MCU "ATmega2560"
> +#define TYPE_ATMEGA16U4_MCU "ATmega16U4"
> +#define TYPE_ATMEGA32U4_MCU "ATmega32U4"
>
>  typedef struct AtmegaMcuState AtmegaMcuState;
>  DECLARE_INSTANCE_CHECKER(AtmegaMcuState, ATMEGA_MCU,
> --
> 2.38.4
>


-- 
Best Regards,
Michael Rolnik

Reply via email to