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


#ifndef INCLUDE_ECXX_PLATFORM_AVRX_PIN_MAPPING_STD_H
#error "this file cannot be included directly"
#endif
#undef INCLUDE_ECXX_PLATFORM_AVRX_PIN_MAPPING_STD_H


#ifndef ECXX_PLATFORM_AVR_PIN_NAME_STD_ABCDEF_H
#define ECXX_PLATFORM_AVR_PIN_NAME_STD_ABCDEF_H


//
// Available ports : A B C D E F (e.g. Arduino variant nona4809)
//

//
// The pin map specified below is based on the Arduino Nano Every board.
//
// NOTE : The pin map has been slightly modified and extended from the one specified by the
//        silkscreen on the Arduino Nano Every board
//


// Pin number ranges
static constexpr uint8_t maxDigitalPinNumber = AVR::DMax;

static constexpr uint8_t minPWMPinNumber  = 14;
static constexpr uint8_t maxPWMPinNumber  = 21;

static constexpr uint8_t minADCPinNumber  =  3;
static constexpr uint8_t maxADCPinNumber  = 27;

static constexpr uint8_t spiPinSS         =  8;
static constexpr uint8_t spiPinMOSI       = 11;
static constexpr uint8_t spiPinMISO       = 12;
static constexpr uint8_t spiPinSCK        = 13;

static constexpr uint8_t twiPinSDA        = 4;
static constexpr uint8_t twiPinSCL        = 5;

static constexpr uint8_t numOfExtInt      = 9;


// Pin number to port number
ECXX_UINT8_ARRAY pin_to_port_number[] = {
             //               Alternate port function (TQFP48)                                          | eCxx pin assignment
             //               4809                                                                      |
    ECXX_PC, // PC 5 **  0 **                                    USART1_ALT_RX                          | UART1_RX
    ECXX_PC, // PC 4 **  1 **                                    USART1_ALT_TX                          | UART1_TX
    ECXX_PA, // PA 0 **  2 **           TCA0_DEF_L0 LUT0_IN0     USART0_DEF_TX                          | UART2_TX
    ECXX_PF, // PF 5 **  3 ** A15       TCB1_ALT                 USART2_ALT_RX                          | A8
    ECXX_PC, // PC 6 **  4 **     EINT2             LUT1_OUT_ALT                                        |
    ECXX_PB, // PB 2 **  5 **     EINT1                          EVOUTB_DEF                             |
    ECXX_PF, // PF 4 **  6 ** A14       TCB0_ALT                 USART2_ALT_TX                          | A9       TIMER0_INTERNAL
    ECXX_PA, // PA 1 **  7 **           TCA0_DEF_L1 LUT0_IN1     USART0_DEF_RX                          | UART2_RX
    ECXX_PE, // PE 3 **  8 ** A11                                              SPI_ALT_SS               | SPI_SS
    ECXX_PB, // PB 0 **  9 **                                    USART3_DEF_TX                          |
    ECXX_PB, // PB 1 ** 10 **                                    USART3_DEF_RX                          |
    ECXX_PE, // PE 0 ** 11 ** A8                                               SPI_ALT_MOSI             | SPI_MOSI
    ECXX_PE, // PE 1 ** 12 ** A9                                               SPI_ALT_MISO             | SPI_MISO
    ECXX_PE, // PE 2 ** 13 ** A10 EINT4                          EVOUTE_DEF    SPI_ALT_SCK              | SPI_SCK  INDICATOR_LED
    ECXX_PD, // PD 3 ** 14 ** A3        TCA0_ALT_H0 LUT2_OUT_DEF                            AC0_N0      | A0       PWM3
    ECXX_PD, // PD 2 ** 15 ** A2  EINT3 TCA0_ALT_L2 LUT2_IN2     EVOUTD_DEF                 AC0_P0      | A1       PWM2
    ECXX_PD, // PD 1 ** 16 ** A1        TCA0_ALT_L1 LUT2_IN1                                AC0_P3      | A2       PWM1
    ECXX_PD, // PD 0 ** 17 ** A0        TCA0_ALT_L0 LUT2_IN0                                            | A3       PWM0
    ECXX_PF, // PF 2 ** 18 ** A12 EINT5             LUT3_IN2     EVOUTF_DEF                             | A4
    ECXX_PF, // PF 3 ** 19 ** A13                   LUT3_OUT_DEF                                        | A5
    ECXX_PD, // PD 4 ** 20 ** A4        TCA0_ALT_H1                                         AC0_P1      | A6       PWM4
    ECXX_PD, // PD 5 ** 21 ** A5        TCA0_ALT_H2                                         AC0_N1      | A7       PWM5
    ECXX_PA, // PA 2 ** 22 **     EINT0 TCA0_DEF_L2 LUT0_IN2     EVOUTA_DEF                 TWI_DEF_SDA | TWI_SDA
    ECXX_PA, // PA 3 ** 23 **           TCA0_DEF_H0 LUT0_OUT_DEF                            TWI_DEF_SCL | TWI_SCL
    ECXX_PB, // PB 5 ** 24 **           TCB3_DEF                 USART3_ALT_RX                          | UART0_RX HOST_PC_COM
    ECXX_PB, // PB 4 ** 25 **           TCB2_ALT                 USART3_ALT_TX                          | UART0_TX HOST_PC_COM
    // --- Extended pin map ---
    ECXX_PD, // PD 6 ** 26 ** A6  EINT8             LUT2_OUT_ALT                            AC0_P2      | A10
    ECXX_PD, // PD 7 ** 27 ** A7                                 EVOUTD_ALT                 AC0_N2      | A11
    ECXX_PA, // PA 4 ** 28 **           TCA0_DEF_H1              USART0_ALT_TX SPI_DEF_MOSI             |
    ECXX_PA, // PA 5 ** 29 **           TCA0_DEF_H2              USART0_ALT_RX SPI_DEF_MISO             |
    ECXX_PA, // PA 6 ** 30 **     EINT6             LUT0_OUT_ALT               SPI_DEF_SCK              |
    ECXX_PA, // PA 7 ** 31 **                                    EVOUTA_ALT    SPI_ALT_SS   AC0_OUT     |
    ECXX_PB, // PB 3 ** 32 **                                                                           |
    ECXX_PC, // PC 0 ** 33 **           TCB2_DEF    LUT1_IN0     USART1_DEF_TX                          |
    ECXX_PC, // PC 1 ** 34 **           TCB3_ALT    LUT1_IN1     USART1_DEF_RX                          |
    ECXX_PC, // PC 2 ** 35 **     EINT7             LUT1_IN2     EVOUTC_DEF                 TWI_ALT_SDA |
    ECXX_PC, // PC 3 ** 36 **                       LUT1_OUT_DEF                            TWI_ALT_SCL |
    ECXX_PC, // PC 7 ** 37 **                                    EVOUTC_ALT                             |
    ECXX_PF, // PF 0 ** 38 **                       LUT3_IN0     USART2_DEF_TX                          |
    ECXX_PF  // PF 1 ** 39 **                       LUT3_IN1     USART2_DEF_RX                          |
};


// Communication ports
#define ECXX_USART0_USART       (&USART3)
#define ECXX_USART0_RX          24
#define ECXX_USART0_TX          25
#define ECXX_USART0_PORT_MUX    PORTMUX_USART3_ALT1_gc
#define ECXX_USART0_RXC_VEC     USART3_RXC_vect
#define ECXX_USART0_DRE_VEC     USART3_DRE_vect
#define ECXX_USART0_DRE_VEC_NUM USART3_DRE_vect_num

#define ECXX_USART1_USART       (&USART1)
#define ECXX_USART1_RX          0
#define ECXX_USART1_TX          1
#define ECXX_USART1_PORT_MUX    PORTMUX_USART1_ALT1_gc
#define ECXX_USART1_RXC_VEC     USART1_RXC_vect
#define ECXX_USART1_DRE_VEC     USART1_DRE_vect
#define ECXX_USART1_DRE_VEC_NUM USART1_DRE_vect_num

#define ECXX_USART2_USART       (&USART0)
#define ECXX_USART2_RX          7
#define ECXX_USART2_TX          2
#define ECXX_USART2_PORT_MUX    PORTMUX_USART0_DEFAULT_gc
#define ECXX_USART2_RXC_VEC     USART0_RXC_vect
#define ECXX_USART2_DRE_VEC     USART0_DRE_vect
#define ECXX_USART2_DRE_VEC_NUM USART0_DRE_vect_num

#define ECXX_SPI_PORT_MUX       PORTMUX_SPI0_ALT2_gc

#define ECXX_TWI_PORT_MUX       PORTMUX_TWI0_DEFAULT_gc


// Configurable custom logic
#define LUT0_IN_PORT      (&PORTA)
#define LUT0_IN0_BM       PIN0_bm
#define LUT0_IN1_BM       PIN1_bm
#define LUT0_IN2_BM       PIN2_bm
#define LUT0_OUT_DEF_PORT (&PORTA)
#define LUT0_OUT_DEF_BM   PIN3_bm
#define LUT0_OUT_ALT_PORT (&PORTA)
#define LUT0_OUT_ALT_BM   PIN6_bm

#define LUT1_IN_PORT      (&PORTC)
#define LUT1_IN0_BM       PIN0_bm
#define LUT1_IN1_BM       PIN1_bm
#define LUT1_IN2_BM       PIN2_bm
#define LUT1_OUT_DEF_PORT (&PORTC)
#define LUT1_OUT_DEF_BM   PIN3_bm
#define LUT1_OUT_ALT_PORT (&PORTC)
#define LUT1_OUT_ALT_BM   PIN6_bm

#define LUT2_IN_PORT      (&PORTD)
#define LUT2_IN0_BM       PIN0_bm
#define LUT2_IN1_BM       PIN1_bm
#define LUT2_IN2_BM       PIN2_bm
#define LUT2_OUT_DEF_PORT (&PORTD)
#define LUT2_OUT_DEF_BM   PIN3_bm
#define LUT2_OUT_ALT_PORT (&PORTD)
#define LUT2_OUT_ALT_BM   PIN6_bm

#define LUT3_IN_PORT      (&PORTF)
#define LUT3_IN0_BM       PIN0_bm
#define LUT3_IN1_BM       PIN1_bm
#define LUT3_IN2_BM       PIN2_bm
#define LUT3_OUT_DEF_PORT (&PORTF)
#define LUT3_OUT_DEF_BM   PIN3_bm
#define LUT3_OUT_ALT_PORT (&PORTF)
#define LUT3_OUT_ALT_BM   0


// Pin number to bit position
ECXX_UINT8_ARRAY pin_to_bit_position[] = {
    PIN5_bp, // PC 5 **  0 **
    PIN4_bp, // PC 4 **  1 **
    PIN0_bp, // PA 0 **  2 **
    PIN5_bp, // PF 5 **  3 **
    PIN6_bp, // PC 6 **  4 **
    PIN2_bp, // PB 2 **  5 **
    PIN4_bp, // PF 4 **  6 **
    PIN1_bp, // PA 1 **  7 **
    PIN3_bp, // PE 3 **  8 **
    PIN0_bp, // PB 0 **  9 **
    PIN1_bp, // PB 1 ** 10 **
    PIN0_bp, // PE 0 ** 11 **
    PIN1_bp, // PE 1 ** 12 **
    PIN2_bp, // PE 2 ** 13 **
    PIN3_bp, // PD 3 ** 14 **
    PIN2_bp, // PD 2 ** 15 **
    PIN1_bp, // PD 1 ** 16 **
    PIN0_bp, // PD 0 ** 17 **
    PIN2_bp, // PF 2 ** 18 **
    PIN3_bp, // PF 3 ** 19 **
    PIN4_bp, // PD 4 ** 20 **
    PIN5_bp, // PD 5 ** 21 **
    PIN2_bp, // PA 2 ** 22 **
    PIN3_bp, // PA 3 ** 23 **
    PIN5_bp, // PB 5 ** 24 **
    PIN4_bp, // PB 4 ** 25 **
    // --- Extended pin map ---
    PIN6_bp, // PD 6 ** 26 **
    PIN7_bp, // PD 7 ** 27 **
    PIN4_bp, // PA 4 ** 28 **
    PIN5_bp, // PA 5 ** 29 **
    PIN6_bp, // PA 6 ** 30 **
    PIN7_bp, // PA 7 ** 31 **
    PIN3_bp, // PB 3 ** 32 **
    PIN0_bp, // PC 0 ** 33 **
    PIN1_bp, // PC 1 ** 34 **
    PIN2_bp, // PC 2 ** 35 **
    PIN3_bp, // PC 3 ** 36 **
    PIN7_bp, // PC 7 ** 37 **
    PIN0_bp, // PF 0 ** 38 **
    PIN1_bp  // PF 1 ** 39 **
};


// Pin number to bit mask
ECXX_UINT8_ARRAY pin_to_bit_mask[] = {
    PIN5_bm, // PC 5 **  0 **
    PIN4_bm, // PC 4 **  1 **
    PIN0_bm, // PA 0 **  2 **
    PIN5_bm, // PF 5 **  3 **
    PIN6_bm, // PC 6 **  4 **
    PIN2_bm, // PB 2 **  5 **
    PIN4_bm, // PF 4 **  6 **
    PIN1_bm, // PA 1 **  7 **
    PIN3_bm, // PE 3 **  8 **
    PIN0_bm, // PB 0 **  9 **
    PIN1_bm, // PB 1 ** 10 **
    PIN0_bm, // PE 0 ** 11 **
    PIN1_bm, // PE 1 ** 12 **
    PIN2_bm, // PE 2 ** 13 **
    PIN3_bm, // PD 3 ** 14 **
    PIN2_bm, // PD 2 ** 15 **
    PIN1_bm, // PD 1 ** 16 **
    PIN0_bm, // PD 0 ** 17 **
    PIN2_bm, // PF 2 ** 18 **
    PIN3_bm, // PF 3 ** 19 **
    PIN4_bm, // PD 4 ** 20 **
    PIN5_bm, // PD 5 ** 21 **
    PIN2_bm, // PA 2 ** 22 **
    PIN3_bm, // PA 3 ** 23 **
    PIN5_bm, // PB 5 ** 24 **
    PIN4_bm, // PB 4 ** 25 **
    // --- Extended pin map ---
    PIN6_bm, // PD 6 ** 26 **
    PIN7_bm, // PD 7 ** 27 **
    PIN4_bm, // PA 4 ** 28 **
    PIN5_bm, // PA 5 ** 29 **
    PIN6_bm, // PA 6 ** 30 **
    PIN7_bm, // PA 7 ** 31 **
    PIN3_bm, // PB 3 ** 32 **
    PIN0_bm, // PC 0 ** 33 **
    PIN1_bm, // PC 1 ** 34 **
    PIN2_bm, // PC 2 ** 35 **
    PIN3_bm, // PC 3 ** 36 **
    PIN7_bm, // PC 7 ** 37 **
    PIN0_bm, // PF 0 ** 38 **
    PIN1_bm, // PF 1 ** 39 **
    PIN6_bm  // PF 6 ** 40 **
};


// Pin number to PWM timer
ECXX_UINT8_ARRAY pin_to_pwm_timer[] = { // Index = pinNumber - minPWMPinNumber
    ECXX_TIMERA0,
    ECXX_TIMERA0,
    ECXX_TIMERA0,
    ECXX_TIMERA0,
    ECXX_NOT_PWM,
    ECXX_NOT_PWM,
    ECXX_TIMERA0,
    ECXX_TIMERA0
};


// Pin number to ADC channel
ECXX_UINT8_ARRAY pin_to_adc_channel[] = { // Index = pinNumber - minADCPinNumber
    15,
    ECXX_NOT_ADC,
    ECXX_NOT_ADC,
    14,
    ECXX_NOT_ADC,
    ECXX_NOT_ADC,
    ECXX_NOT_ADC,
    ECXX_NOT_ADC,
    ECXX_NOT_ADC,
    ECXX_NOT_ADC,
     3,
     2,
     1,
     0,
    12,
    13,
     4,
     5,
    ECXX_NOT_ADC,
    ECXX_NOT_ADC,
    ECXX_NOT_ADC,
    ECXX_NOT_ADC,
     6,
     7
};


#endif
