/*
  pins_arduino.h - Pin definition functions for Arduino
  Part of Arduino - http://www.arduino.cc/

  Copyright (c) 2007 David A. Mellis

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General
  Public License along with this library; if not, write to the
  Free Software Foundation, Inc., 59 Temple Place, Suite 330,
  Boston, MA  02111-1307  USA
*/

#ifndef Pins_Arduino_h
#define Pins_Arduino_h

#include "wiring_constants.h"

#ifdef __cplusplus
extern "C" {
#endif

#include "mik32_hal_gpio.h"
#include "mik32_hal_timer32.h"

// total number of pins available for initialization
#define PINS_COMMON_QTY   24
#define pinCommonQty()    (PINS_COMMON_QTY)

extern bool spi0NssPinIsBlocked;
extern bool spi1NssPinIsBlocked;

// analog pins
#define PIN_A0        (14)
#define PIN_A1        (15)
#define PIN_A2        (16)
#define PIN_A3        (17)
// there are D18 and D19 between them
#define PIN_A4        (20)
#define PIN_A5        (21)
static const uint8_t A0 = PIN_A0;
static const uint8_t A1 = PIN_A1;
static const uint8_t A2 = PIN_A2;
static const uint8_t A3 = PIN_A3;
static const uint8_t A4 = PIN_A4;
static const uint8_t A5 = PIN_A5;

// digital pins
// D0...D13, D18, D19

// User led and button
#define LED_BUILTIN   (22)
#define BTN_BUILTIN   (23)

// determines the port address by the board pin number to which this pin belongs on the MCU
GPIO_TypeDef* digitalPinToPort(uint32_t digPinNumber);
// determines the pin address inside the port by the board pin number
HAL_PinsTypeDef digitalPinToBitMask(uint32_t digPinNumber);
// the function returns a reference to the OUTPUT address of the GPIO register
volatile uint32_t* portOutputRegister(GPIO_TypeDef* GPIO_x);
// the function returns a reference to the STATE address of the GPIO register
volatile uint32_t* portInputRegister(GPIO_TypeDef* GPIO_x);
// the function initializes additional MCU pins depending on the specified pin number
void additionalPinsInit(uint32_t PinNumber);
static inline void additionalPinsDeinit(uint32_t PinNumber){}

// UART
// available uarts quantity
#define SERIAL_PORT_QTY 2
#define DEFAULT_SERIAL  Serial0

// ADC
#define MCU_ADC_RESOLUTION    12 // bits
// determines the ADC channel number by the board pin number
uint32_t analogInputToChannelNumber(uint32_t PinNumber);

// PWM
#define PWM_FREQUENCY_MAX         1000000 // Hz
static inline __attribute__((always_inline)) bool digitalPinHasPWM(uint8_t p)   
{
  // if spi is in use D9 or D10 cannot work as pwm
  if (p == 3 || p == 5 || p == 6 || (p >= 11 && p <= 13) || ((p == 9) && !spi0NssPinIsBlocked) || ((p == 10) && !spi1NssPinIsBlocked))
    return true;
  return false;
}
// return true if digitalPin configured as pwm
int8_t digitalPinPwmIsOn(uint8_t digitalPin);
// determines which timer the pin belongs to
TIMER32_TypeDef* pwmPinToTimer(uint32_t digPinNumber);
// determines which timer channel the pin belongs to
HAL_TIMER32_CHANNEL_IndexTypeDef pwmPinToTimerChannel(uint32_t digPinNumber);

// SPI
#define SPI_COMMON_QTY  2
#define DEFAULT_SPI     SPI1

#define PIN_SPI_SS      10
#define PIN_SPI_MOSI    11
#define PIN_SPI_MISO    12
#define PIN_SPI_SCK     13
static const uint8_t SS   = PIN_SPI_SS;
static const uint8_t MOSI = PIN_SPI_MOSI;
static const uint8_t MISO = PIN_SPI_MISO;
static const uint8_t SCK  = PIN_SPI_SCK;

#define PIN_SPI0_SS      9
#define PIN_SPI0_MOSI    5
#define PIN_SPI0_MISO    3
#define PIN_SPI0_SCK     6
static const uint8_t SS1   = PIN_SPI0_SS;
static const uint8_t MOSI1 = PIN_SPI0_MOSI;
static const uint8_t MISO1 = PIN_SPI0_MISO;
static const uint8_t SCK1  = PIN_SPI0_SCK;

// config SEL_NSS1 to replace D10 to different controller pin,
// because NSS which is D9/D10 by default is needed to spi 
void spi_onBegin(uint8_t spiNum);
void spi_onEnd(uint8_t spiNum);

// I2C
#define I2C_COMMON_QTY  (1)
#define DEFAULT_WIRE    Wire1 // use I2C1 by default
#define PIN_WIRE_SDA    (18)
#define PIN_WIRE_SCL    (19)
static const uint8_t SDA = PIN_WIRE_SDA;
static const uint8_t SCL = PIN_WIRE_SCL;
// available frequencies
#define WIRE_FREQ_100K    100000
#define WIRE_FREQ_400K    400000
#define WIRE_FREQ_1000K   1000000

// interrupts
#define EXTERNAL_INTERRUPTS_QTY   8
extern uint8_t interruptInfo[EXTERNAL_INTERRUPTS_QTY][3];
// determines the board pin number by interrupt number
#define interruptToDigitalPin(interruptNum)   (interruptInfo[interruptNum][0])
// determines gpio interrupt line by interrupt number
#define interruptToGpioIntLine(interruptNum)  ((uint8_t)interruptInfo[interruptNum][1])
// determines gpio interrupt mux by interrupt number
#define interruptToGpioIntMux(interruptNum)   ((uint8_t)interruptInfo[interruptNum][2])
// determines interrupt number by the board pin number 
int8_t digitalPinToInterrupt(uint32_t digPinNumber);
// determines interrupt number by the gpio interrupt line
int8_t gpioIntLineToInterrupt(uint32_t gpioIntLine);
// determines gpio interrupt mux by the board pin number
int8_t digitalPinToGpioIntMux(uint8_t digPinNumber);
// determines gpio interrupt line by the board pin number
int8_t digitalPinToGpioIntLine(uint8_t digPinNumber);




#ifdef __cplusplus
}
#endif

#endif
