From d3dc49e2ab2630e0bf9eea06e45b885a5851e939 Mon Sep 17 00:00:00 2001
From: Matthew Blue <matthew.blue.neuro@gmail.com>
Date: Sat, 17 Mar 2018 16:23:14 -0400
Subject: [PATCH] cpu/atmega_common: Support for ATmega1284P

---
 cpu/atmega_common/periph/adc.c   |  5 ++++-
 cpu/atmega_common/periph/gpio.c  | 25 +++++++++++++++++++++++++
 cpu/atmega_common/periph/spi.c   |  3 +++
 cpu/atmega_common/periph/timer.c |  2 ++
 4 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/cpu/atmega_common/periph/adc.c b/cpu/atmega_common/periph/adc.c
index 81bc224c9f..db6fd79502 100644
--- a/cpu/atmega_common/periph/adc.c
+++ b/cpu/atmega_common/periph/adc.c
@@ -67,6 +67,9 @@ int adc_init(adc_t line)
 #if defined(CPU_ATMEGA328P)
     DDRC &= ~(1 << line);
     PORTC &= ~(1 << line);
+#elif defined(CPU_ATMEGA1284P)
+    DDRA &= ~(1 << line);
+    PORTA &= ~(1 << line);
 #elif defined(CPU_ATMEGA2560) || defined(CPU_ATMEGA1281)
     if (line < 8) {
         DDRF  &= ~(1 << line);
@@ -108,7 +111,7 @@ int adc_sample(adc_t line, adc_res_t res)
     _prep();
 
     /* set conversion channel */
-#if defined(CPU_ATMEGA328P) || defined(CPU_ATMEGA1281)
+#if defined(CPU_ATMEGA328P) || defined(CPU_ATMEGA1281) || defined(CPU_ATMEGA1284P)
     ADMUX &= 0xf0;
     ADMUX |= line;
 #elif defined(CPU_ATMEGA2560) || defined(CPU_ATMEGA256RFR2)
diff --git a/cpu/atmega_common/periph/gpio.c b/cpu/atmega_common/periph/gpio.c
index 28d48bd7b7..4d61c08e58 100644
--- a/cpu/atmega_common/periph/gpio.c
+++ b/cpu/atmega_common/periph/gpio.c
@@ -140,6 +140,10 @@ int gpio_init_int(gpio_t pin, gpio_mode_t mode, gpio_flank_t flank,
          || (_port_num(pin) != PORT_D && _port_num(pin) != PORT_E)
 #elif defined(CPU_ATMEGA328P)
          || (pin_num < 2) || (_port_num(pin) != PORT_D)
+#elif defined(CPU_ATMEGA1284P)
+         || (_port_num(pin) == PORT_B && pin_num != 2)
+         || (_port_num(pin) == PORT_D && pin_num < 2)
+         || (_port_num(pin) != PORT_D && _port_num(pin) != PORT_D)
 #endif
          || ((mode != GPIO_IN) && (mode != GPIO_IN_PU))) {
         return -1;
@@ -153,6 +157,11 @@ int gpio_init_int(gpio_t pin, gpio_mode_t mode, gpio_flank_t flank,
 #if defined(CPU_ATMEGA328P)
     /* INT pins start at PD2 instead of at PD0 */
     pin_num -= 2;
+#elif defined(CPU_ATMEGA1284P)
+    /* INT pins start at PD2 instead of at PD0 on PORT_D */
+    if (_port_num(pin) == PORT_D) {
+        pin_num -= 2;
+    }
 #endif
 
     EIMSK |= (1 << pin_num);
@@ -186,6 +195,14 @@ void gpio_irq_enable(gpio_t pin)
 #if defined(CPU_ATMEGA328P)
     /* INT pins start at PD2 instead of at PD0 */
     EIMSK |= (1 << (_pin_num(pin) - 2));
+#elif defined(CPU_ATMEGA1284P)
+    /* INT pins start at PD2 instead of at PD0 on PORT_D */
+    if (_port_num(pin) == PORT_D) {
+        EIMSK |= (1 << (_pin_num(pin) - 2));
+    }
+    else {
+        EIMSK |= (1 << _pin_num(pin));
+    }
 #else
     EIMSK |= (1 << _pin_num(pin));
 #endif
@@ -196,6 +213,14 @@ void gpio_irq_disable(gpio_t pin)
 #if defined(CPU_ATMEGA328P)
     /* INT pins start at PD2 instead of at PD0 */
     EIMSK &= ~(1 << (_pin_num(pin) - 2));
+#elif defined (CPU_ATMEGA1284P)
+    /* INT pins start at PD2 instead of at PD0 on PORT_D */
+    if (_port_num(pin) == PORT_D) {
+        EIMSK &= ~(1 << (_pin_num(pin) - 2));
+    }
+    else {
+        EIMSK &= ~(1 << _pin_num(pin));
+    }
 #else
     EIMSK &= ~(1 << _pin_num(pin));
 #endif
diff --git a/cpu/atmega_common/periph/spi.c b/cpu/atmega_common/periph/spi.c
index fb2fcd2e40..de4ac97cfc 100644
--- a/cpu/atmega_common/periph/spi.c
+++ b/cpu/atmega_common/periph/spi.c
@@ -57,6 +57,9 @@ void spi_init_pins(spi_t bus)
 #if defined (CPU_ATMEGA328P)
     DDRB |= ((1 << DDB2) | (1 << DDB3) | (1 << DDB5));
 #endif
+#if defined (CPU_ATMEGA1284P)
+    DDRB |= ((1 << DDB4) | (1 << DDB5) | (1 << DDB7));
+#endif
 #if defined (CPU_ATMEGA256RFR2)
     /* Master: PB3 MISO set to out
      *         PB2 MOSI set to input by hardware
diff --git a/cpu/atmega_common/periph/timer.c b/cpu/atmega_common/periph/timer.c
index 5a463e22fe..9eb2b1a87f 100644
--- a/cpu/atmega_common/periph/timer.c
+++ b/cpu/atmega_common/periph/timer.c
@@ -212,10 +212,12 @@ ISR(TIMER_1_ISRB, ISR_BLOCK)
     _isr(1, 1);
 }
 
+#ifdef TIMER_1_ISRC
 ISR(TIMER_1_ISRC, ISR_BLOCK)
 {
     _isr(1, 2);
 }
+#endif /* TIMER_1_ISRC */
 #endif /* TIMER_1 */
 
 #ifdef TIMER_2
-- 
GitLab