/*
 * Copyright (C) 2020-2021 Aloysius Indrayanto
 *
 * This file is part of the eCxx library, see LICENSE file for the license details.
 */


#ifndef ECXX_PLATFORM_AVR_PIN_MAPPING_H
#define ECXX_PLATFORM_AVR_PIN_MAPPING_H


//
// Internal constants
//

// Special marker
#define ECXX_NOT_IO_REG nullptr
#define ECXX_NOT_PWM    0
#define ECXX_NOT_ADC    0

// Port number
#define ECXX_PA   1
#define ECXX_PB   2
#define ECXX_PC   3
#define ECXX_PD   4
#define ECXX_PE   5
#define ECXX_PF   6
#define ECXX_PG   7
#define ECXX_PH   8
#define ECXX_PJ  10
#define ECXX_PK  11
#define ECXX_PL  12

#define ECXX_PX 255 /* Any port or mixed port */

// Timer
#define ECXX_TIMER0   1
#define ECXX_TIMER0A  2
#define ECXX_TIMER0B  3
#define ECXX_TIMER1A  4
#define ECXX_TIMER1B  5
#define ECXX_TIMER1C  6
#define ECXX_TIMER2   7
#define ECXX_TIMER2A  8
#define ECXX_TIMER2B  9
#define ECXX_TIMER3A 10
#define ECXX_TIMER3B 11
#define ECXX_TIMER3C 12
#define ECXX_TIMER4A 13
#define ECXX_TIMER4B 14
#define ECXX_TIMER4C 15
#define ECXX_TIMER4D 16
#define ECXX_TIMER5A 17
#define ECXX_TIMER5B 18
#define ECXX_TIMER5C 19

// A special macro to be used to declare array for direct digital configure/read/write
// as well as for normal digital configure/read/write
#ifdef ECXX_DECLARE_ARRAY_FOR_DDX
    #define ECXX_UINT8_ARRAY static constexpr uint8_t
#else
    #define ECXX_UINT8_ARRAY static const uint8_t PROGMEM
#endif


namespace eCxx {


//
// Include the appropriate standard pin mapping header file
//
#define INCLUDE_ECXX_PLATFORM_AVR_PIN_MAPPING_STD_H


#if defined(__AVR_ATmega8__  ) || defined(__AVR_ATmega8A__  ) ||                                                                                                \
    defined(__AVR_ATmega48__ ) || defined(__AVR_ATmega48A__ ) || defined(__AVR_ATmega48P__ ) || defined(__AVR_ATmega48PA__ ) || defined(__AVR_ATmega48PB__ ) || \
    defined(__AVR_ATmega88__ ) || defined(__AVR_ATmega88A__ ) || defined(__AVR_ATmega88P__ ) || defined(__AVR_ATmega88PA__ ) || defined(__AVR_ATmega88PB__ ) || \
    defined(__AVR_ATmega168__) || defined(__AVR_ATmega168A__) || defined(__AVR_ATmega168P__) || defined(__AVR_ATmega168PA__) || defined(__AVR_ATmega168PB__) || \
    defined(__AVR_ATmega328__) ||                                defined(__AVR_ATmega328P__)

    #include "PinMapping_Std_XBCD.h"


#elif defined(__AVR_ATmega328PB__)

    #include "PinMapping_Std_XBCDE.h"


#elif defined(__AVR_ATmega16__  ) || defined(__AVR_ATmega16A__ ) ||                                                                 \
                                     defined(__AVR_ATmega164A__) || defined(__AVR_ATmega164P__ ) || defined(__AVR_ATmega164PA__) || \
      defined(__AVR_ATmega32__  ) || defined(__AVR_ATmega32A__ ) ||                                                                 \
                                     defined(__AVR_ATmega324A__) || defined(__AVR_ATmega324P__ ) || defined(__AVR_ATmega324PA__) || \
      defined(__AVR_ATmega644__ ) || defined(__AVR_ATmega644A__) || defined(__AVR_ATmega644P__ ) || defined(__AVR_ATmega644PA__) || \
      defined(__AVR_ATmega1284__) ||                                defined(__AVR_ATmega1284P__)

    #include "PinMapping_Std_ABCD.h"


#elif defined(__AVR_ATmega64__ ) || defined(__AVR_ATmega64A__ ) || \
      defined(__AVR_ATmega128__) || defined(__AVR_ATmega128A__)

    #include "PinMapping_Std_ABCDEFG.h"


#elif defined(__AVR_ATmega640__) || defined(__AVR_ATmega1280__) || defined(__AVR_ATmega2560__)

    #include "PinMapping_Std_ABCDEFGHXJKL.h"


#elif defined(__AVR_ATmega16U4__) || defined(__AVR_ATmega32U4__)

    #include "PinMapping_Std_XBCDEF.h"


#elif defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__)

    #include "PinMapping_Std_ABCDEF.h"


#endif


#ifdef INCLUDE_ECXX_PLATFORM_AVR_PIN_MAPPING_STD_H
    #error "unsupported AVR MCU"
#endif


} // namespace eCxx


#endif
