/*
 * 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_AXCDXF_H
#define ECXX_PLATFORM_AVR_PIN_NAME_STD_AXCDXF_H


//
// Available ports : A C D F (no Arduino variant)
//

//
// The pin map specified below is based on the Thinary ATmega4808 board that was
// manufactured by Thinary Electronic:
//     https://github.com/Thinary/ThinaryArduino/tree/master/Thinary-megaavr
//     https://www.aliexpress.com/item/4000160961890.html
//
// NOTE : The pin map has been modified from the one specified by the silkscreen
//        on the Thinary ATmega4808 board
//


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

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

static constexpr uint8_t minADCPinNumber  = 14;
static constexpr uint8_t maxADCPinNumber  = 25;

static constexpr uint8_t spiPinSS         = 9;
static constexpr uint8_t spiPinMOSI       = 6;
static constexpr uint8_t spiPinMISO       = 7;
static constexpr uint8_t spiPinSCK        = 8;

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

static constexpr uint8_t numOfExtInt      = 6;


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


// Communication ports
#define ECXX_USART0_USART       (&USART2)
#define ECXX_USART0_RX          0
#define ECXX_USART0_TX          1
#define ECXX_USART0_PORT_MUX    PORTMUX_USART2_DEFAULT_gc
#define ECXX_USART0_RXC_VEC     USART2_RXC_vect
#define ECXX_USART0_DRE_VEC     USART2_DRE_vect
#define ECXX_USART0_DRE_VEC_NUM USART2_DRE_vect_num
#define ECXX_USART0_PORT        PORTF
#define ECXX_USART0_PORT_BM     (PIN1_bm | PIN0_bm)

#define ECXX_USART1_USART       (&USART0)
#define ECXX_USART1_RX          3
#define ECXX_USART1_TX          2
#define ECXX_USART1_PORT_MUX    PORTMUX_USART0_DEFAULT_gc
#define ECXX_USART1_RXC_VEC     USART0_RXC_vect
#define ECXX_USART1_DRE_VEC     USART0_DRE_vect
#define ECXX_USART1_DRE_VEC_NUM USART0_DRE_vect_num

#define ECXX_USART2_USART       (&USART1)
#define ECXX_USART2_RX          12
#define ECXX_USART2_TX          11
#define ECXX_USART2_PORT_MUX    PORTMUX_USART1_DEFAULT_gc
#define ECXX_USART2_RXC_VEC     USART1_RXC_vect
#define ECXX_USART2_DRE_VEC     USART1_DRE_vect
#define ECXX_USART2_DRE_VEC_NUM USART1_DRE_vect_num

#define ECXX_SPI_PORT_MUX       PORTMUX_SPI0_DEFAULT_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   0

#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[] = {
    PIN1_bp, // PF 1 **  0 **
    PIN0_bp, // PF 0 **  1 **
    PIN0_bp, // PA 0 **  2 **
    PIN1_bp, // PA 1 **  3 **
    PIN2_bp, // PA 2 **  4 **
    PIN3_bp, // PA 3 **  5 **
    PIN4_bp, // PA 4 **  6 **
    PIN5_bp, // PA 5 **  7 **
    PIN6_bp, // PA 6 **  8 **
    PIN7_bp, // PA 7 **  9 **
    PIN3_bp, // PC 3 ** 10 **
    PIN0_bp, // PC 0 ** 11 **
    PIN1_bp, // PC 1 ** 12 **
    PIN2_bp, // PC 2 ** 13 **
    PIN0_bp, // PD 0 ** 14 **
    PIN1_bp, // PD 1 ** 15 **
    PIN2_bp, // PD 2 ** 16 **
    PIN3_bp, // PD 3 ** 17 **
    PIN2_bp, // PF 2 ** 18 **
    PIN3_bp, // PF 3 ** 19 **
    PIN4_bp, // PF 4 ** 20 **
    PIN5_bp, // PF 5 ** 21 **
    PIN4_bp, // PD 4 ** 22 **
    PIN5_bp, // PD 5 ** 23 **
    PIN6_bp, // PD 6 ** 24 **
    PIN7_bp  // PD 7 ** 25 **
};


// Pin number to bit mask
ECXX_UINT8_ARRAY pin_to_bit_mask[] = {
    PIN1_bm, // PF 1 **  0 **
    PIN0_bm, // PF 0 **  1 **
    PIN0_bm, // PA 0 **  2 **
    PIN1_bm, // PA 1 **  3 **
    PIN2_bm, // PA 2 **  4 **
    PIN3_bm, // PA 3 **  5 **
    PIN4_bm, // PA 4 **  6 **
    PIN5_bm, // PA 5 **  7 **
    PIN6_bm, // PA 6 **  8 **
    PIN7_bm, // PA 7 **  9 **
    PIN3_bm, // PC 3 ** 10 **
    PIN0_bm, // PC 0 ** 11 **
    PIN1_bm, // PC 1 ** 12 **
    PIN2_bm, // PC 2 ** 13 **
    PIN0_bm, // PD 0 ** 14 **
    PIN1_bm, // PD 1 ** 15 **
    PIN2_bm, // PD 2 ** 16 **
    PIN3_bm, // PD 3 ** 17 **
    PIN2_bm, // PF 2 ** 18 **
    PIN3_bm, // PF 3 ** 19 **
    PIN4_bm, // PF 4 ** 20 **
    PIN5_bm, // PF 5 ** 21 **
    PIN4_bm, // PD 4 ** 22 **
    PIN5_bm, // PD 5 ** 23 **
    PIN6_bm, // PD 6 ** 24 **
    PIN7_bm  // PD 7 ** 25 **
};


// 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_NOT_PWM,
    ECXX_NOT_PWM,
    ECXX_TIMERA0,
    ECXX_TIMERA0
};


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


#endif
