/*
 * 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_AVR_PIN_MAPPING_STD_H
#error "this file cannot be included directly"
#endif
#undef INCLUDE_ECXX_PLATFORM_AVR_PIN_MAPPING_STD_H


#ifndef ECXX_PLATFORM_AVR_PIN_MAPPING_STD_XBCDEF_H
#define ECXX_PLATFORM_AVR_PIN_MAPPING_STD_XBCDEF_H


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


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

static constexpr uint8_t minPWMPinNumber[1]  = {  5 };
static constexpr uint8_t maxPWMPinNumber[1]  = { 10 };

static constexpr uint8_t minADCPinNumber     = 18;
static constexpr uint8_t maxADCPinNumber     = 23;
static constexpr uint8_t adcPortLow          = ECXX_PF;
static constexpr uint8_t adcPortHigh         = ECXX_NOT_ADC;

static constexpr uint8_t spiPinMISO          = AVR::SPI_MISO;
static constexpr uint8_t spiPinMOSI          = AVR::SPI_MOSI;
static constexpr uint8_t spiPinSCK           = AVR::SPI_SCK;
static constexpr uint8_t spiPinSS            = AVR::SPI_SS; // ** LEONARDO - TXLED (NO ON-BOARD PIN) **

static constexpr uint8_t twiPinSDA           = AVR::TWI_SDA;
static constexpr uint8_t twiPinSCL           = AVR::TWI_SCL;


// PWM pins [group][set][pin/timer]
static constexpr uint8_t pwm_pins[1][6][2] = { {
    {  5, ECXX_TIMER3A },
    {  6, ECXX_TIMER4D },
    {  0, ECXX_NOT_PWM },
    {  0, ECXX_NOT_PWM },
    {  9, ECXX_TIMER1A },
    { 10, ECXX_TIMER1B }
} };


// Digital pin number to port number
ECXX_UINT8_ARRAY pin_to_pnum[] = {
             //               Alternate port function (TQFP44)
             //               32U4
    ECXX_PD, // PD 2 **  0 ** INT2/RXD1 USART1_RX
    ECXX_PD, // PD 3 **  1 ** INT3/TXD1 USART1_TX
    ECXX_PD, // PD 1 **  2 ** INT1      TWI_SDA
    ECXX_PD, // PD 0 **  3 ** INT0      TWI_SCL
    ECXX_PD, // PD 4 **  4 **
    ECXX_PC, // PC 6 **  5 ** OC3A               PWM5
    ECXX_PD, // PD 7 **  6 ** OC4D               PWM6
    ECXX_PE, // PE 6 **  7 ** INT6
    ECXX_PB, // PB 4 **  8 **
    ECXX_PB, // PB 5 **  9 ** OC1A               PWM9
    ECXX_PB, // PB 6 ** 10 ** OC1B               PWM10
    ECXX_PB, // PB 7 ** 11 ** OC0A               TIMER0_INTERNAL
    ECXX_PD, // PD 6 ** 12 **
    ECXX_PC, // PC 7 ** 13 **                    INDICATOR_LED
    ECXX_PB, // PB 3 ** 14 **           SPI_MISO
    ECXX_PB, // PB 1 ** 15 **           SPI_SCK
    ECXX_PB, // PB 2 ** 16 **           SPI_MOSI
    ECXX_PB, // PB 0 ** 17 **           SPI_SS   ** LEONARDO - TXLED (NO ON-BOARD PIN) **
    ECXX_PF, // PF 7 ** 18 ** A0
    ECXX_PF, // PF 6 ** 19 ** A1
    ECXX_PF, // PF 5 ** 20 ** A2
    ECXX_PF, // PF 4 ** 21 ** A3
    ECXX_PF, // PF 1 ** 22 ** A4
    ECXX_PF, // PF 0 ** 23 ** A5
    ECXX_PD, // PD 4 ** 24 **                    ** LEONARDO - A6    (SHARED WITH D4 ) **
    ECXX_PD, // PD 7 ** 25 **                    ** LEONARDO - A7    (SHARED WITH D6 ) **
    ECXX_PB, // PB 4 ** 26 **                    ** LEONARDO - A8    (SHARED WITH D8 ) **
    ECXX_PB, // PB 5 ** 27 **                    ** LEONARDO - A9    (SHARED WITH D9 ) **
    ECXX_PB, // PB 6 ** 28 **                    ** LEONARDO - A10   (SHARED WITH D10) **
    ECXX_PD, // PD 6 ** 29 **                    ** LEONARDO - A11   (SHARED WITH D12) **
    ECXX_PD  // PD 5 ** 30 **                    ** LEONARDO - RXLED (NO ON-BOARD PIN) **
};


// Digital pin number to port bit mask
ECXX_UINT8_ARRAY pin_to_bitmask[] = {
    _BV(2), // PD 2 **  0 **
    _BV(3), // PD 3 **  1 **
    _BV(1), // PD 1 **  2 **
    _BV(0), // PD 0 **  3 **
    _BV(4), // PD 4 **  4 **
    _BV(6), // PC 6 **  5 **
    _BV(7), // PD 7 **  6 **
    _BV(6), // PE 6 **  7 **
    _BV(4), // PB 4 **  8 **
    _BV(5), // PB 5 **  9 **
    _BV(6), // PB 6 ** 10 **
    _BV(7), // PB 7 ** 11 **
    _BV(6), // PD 6 ** 12 **
    _BV(7), // PC 7 ** 13 **
    _BV(3), // PB 3 ** 14 **
    _BV(1), // PB 1 ** 15 **
    _BV(2), // PB 2 ** 16 **
    _BV(0), // PB 0 ** 17 **
    _BV(7), // PF 7 ** 18 **
    _BV(6), // PF 6 ** 19 **
    _BV(5), // PF 5 ** 20 **
    _BV(4), // PF 4 ** 21 **
    _BV(1), // PF 1 ** 22 **
    _BV(0), // PF 0 ** 23 **
    _BV(4), // PD 4 ** 24 **
    _BV(7), // PD 7 ** 25 **
    _BV(4), // PB 4 ** 26 **
    _BV(5), // PB 5 ** 27 **
    _BV(6), // PB 6 ** 28 **
    _BV(7), // PD 6 ** 29 **
    _BV(5)  // PD 5 ** 30 **
};


// Port number to direction SFR
static constexpr volatile uint8_t* const pnum_to_DDR[] = {
    ECXX_NOT_IO_REG,
    ECXX_NOT_IO_REG,
    &DDRB,
    &DDRC,
    &DDRD,
    &DDRE,
    &DDRF
};


// Port number to output SFR
static constexpr volatile uint8_t* const pnum_to_PORT[] = {
    ECXX_NOT_IO_REG,
    ECXX_NOT_IO_REG,
    &PORTB,
    &PORTC,
    &PORTD,
    &PORTE,
    &PORTF
};


// Port number to input SFR
static constexpr volatile uint8_t* const pnum_to_PIN[] = {
    ECXX_NOT_IO_REG,
    ECXX_NOT_IO_REG,
    &PINB,
    &PINC,
    &PIND,
    &PINE,
    &PINF
};


#endif
