/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

#include "hal/hal_gpio.h"
#include "mcu/cmsis_nvic.h"
#include "mcu/stm32_hal.h"
#include "stm32_common/mcu.h"
#include <assert.h>

 /* XXX: Notes
 * 1) Right now, we are not disabling the NVIC interrupt source; we only
 * disable the external interrupt from occurring. Dont think either way
 * to do it is an issue... when we release we may want to disable the NVIC
 *
 * 2) investigate how thread safe these routines are. HAL_GPIO_Init, for
 * example. Looks like if it gets interrupted while doing config an error
 * may occur. Read/modify write could cause screw-ups.
 *
 * 3) Currently, this code does not change the interrupt priority of the
 * external interrupt vectors in the NVIC. The application developer must
 * decide on the priority level for each external interrupt and program that
 * by using the CMSIS NVIC API  (NVIC_SetPriority and NVIC_SetPriorityGrouping)
 *
 * 4) The code probably does not handle "re-purposing" gpio very well.
 * "Re-purposing" means changing a gpio from input to output, or calling
 * gpio_init_in and expecting previously enabled interrupts to be stopped.
 *
 * 5) Possibly add access to HAL_GPIO_DeInit.
 */

#define GPIO_MASK(pin)      (1 << MCU_GPIO_PIN_NUM(pin))

#ifndef GPIOA
#   define GPIOA    0
#endif
#ifndef GPIOB
#   define GPIOB    0
#endif
#ifndef GPIOC
#   define GPIOC    0
#endif
#ifndef GPIOD
#   define GPIOD    0
#endif
#ifndef GPIOE
#   define GPIOE    0
#endif
#ifndef GPIOF
#   define GPIOF    0
#endif
#ifndef GPIOG
#   define GPIOG    0
#endif
#ifndef GPIOH
#   define GPIOH    0
#endif
#ifndef GPIOI
#   define GPIOI    0
#endif
#ifndef GPIOJ
#   define GPIOJ    0
#endif
#ifndef GPIOK
#   define GPIOK    0
#endif


#if defined GPIOK_BASE
#   define  HAL_GPIO_PORT_COUNT   (11)
#   define  HAL_GPIO_PORT_LIST    GPIOA,GPIOB,GPIOC,GPIOD,GPIOE,GPIOF,GPIOG,GPIOH,GPIOI,GPIOJ,GPIOK
#elif defined GPIOJ_BASE
#   define  HAL_GPIO_PORT_COUNT   (10)
#   define  HAL_GPIO_PORT_LIST    GPIOA,GPIOB,GPIOC,GPIOD,GPIOE,GPIOF,GPIOG,GPIOH,GPIOI,GPIOJ
#elif defined GPIOI_BASE
#   define  HAL_GPIO_PORT_COUNT   (9)
#   define  HAL_GPIO_PORT_LIST    GPIOA,GPIOB,GPIOC,GPIOD,GPIOE,GPIOF,GPIOG,GPIOH,GPIOI
#elif defined GPIOH_BASE
#   define  HAL_GPIO_PORT_COUNT   (8)
#   define  HAL_GPIO_PORT_LIST    GPIOA,GPIOB,GPIOC,GPIOD,GPIOE,GPIOF,GPIOG,GPIOH
#elif defined GPIOG_BASE
#   define  HAL_GPIO_PORT_COUNT   (7)
#   define  HAL_GPIO_PORT_LIST    GPIOA,GPIOB,GPIOC,GPIOD,GPIOE,GPIOF,GPIOG
#elif defined GPIOF_BASE
#   define  HAL_GPIO_PORT_COUNT   (6)
#   define  HAL_GPIO_PORT_LIST    GPIOA,GPIOB,GPIOC,GPIOD,GPIOE,GPIOF
#elif defined GPIOE_BASE
#   define  HAL_GPIO_PORT_COUNT   (5)
#   define  HAL_GPIO_PORT_LIST    GPIOA,GPIOB,GPIOC,GPIOD,GPIOE
#elif defined GPIOD_BASE
#   define  HAL_GPIO_PORT_COUNT   (4)
#   define  HAL_GPIO_PORT_LIST    GPIOA,GPIOB,GPIOC,GPIOD
#elif defined GPIOC_BASE
#   define  HAL_GPIO_PORT_COUNT   (3)
#   define  HAL_GPIO_PORT_LIST    GPIOA,GPIOB,GPIOC
#elif defined GPIOB_BASE
#   define  HAL_GPIO_PORT_COUNT   (2)
#   define  HAL_GPIO_PORT_LIST    GPIOA,GPIOB
#elif defined GPIOA_BASE
#   define  HAL_GPIO_PORT_COUNT   (1)
#   define  HAL_GPIO_PORT_LIST    GPIOA
#else
#   error "No GPIO ports found - MCU not supported!"
#endif


/* Port index to port address map */
static GPIO_TypeDef * const portmap[HAL_GPIO_PORT_COUNT] =
{
    HAL_GPIO_PORT_LIST
};

/* Storage for GPIO callbacks. */
struct gpio_irq_obj
{
    void *arg;
    hal_gpio_irq_handler_t isr;
};

static struct gpio_irq_obj gpio_irq_handlers[16];

struct ext_irqs
{
#if !MYNEWT_VAL(MCU_STM32L0)
    volatile uint32_t irq0;
    volatile uint32_t irq1;
    volatile uint32_t irq2;
    volatile uint32_t irq3;
    volatile uint32_t irq4;
    volatile uint32_t irq9_5;
    volatile uint32_t irq15_10;
#else
    volatile uint32_t irq0_1;
    volatile uint32_t irq2_3;
    volatile uint32_t irq4_15;
#endif
};
struct ext_irqs ext_irq_counts;

/**
 * ext irq handler
 *
 * Handles the gpio interrupt attached to a gpio pin.
 *
 * @param index
 */
static void
ext_irq_handler(int index)
{
    uint32_t mask;

    mask = 1 << index;
    if (__HAL_GPIO_EXTI_GET_IT(mask) != RESET) {
        __HAL_GPIO_EXTI_CLEAR_IT(mask);
        gpio_irq_handlers[index].isr(gpio_irq_handlers[index].arg);
    }
}

#if !MYNEWT_VAL(MCU_STM32L0)
/* External interrupt 0 */
static void
ext_irq0(void)
{
    ++ext_irq_counts.irq0;
    ext_irq_handler(0);
}

/* External interrupt 1 */
static void
ext_irq1(void)
{
    ++ext_irq_counts.irq1;
    ext_irq_handler(1);
}

/* External interrupt 2 */
static void
ext_irq2(void)
{
    ++ext_irq_counts.irq2;
    ext_irq_handler(2);
}

/* External interrupt 3 */
static void
ext_irq3(void)
{
    ++ext_irq_counts.irq3;
    ext_irq_handler(3);
}

/**
 * ext irq4
 *
 *  External interrupt handler for external interrupt 4.
 *
 */
static void
ext_irq4(void)
{
    ++ext_irq_counts.irq4;
    ext_irq_handler(4);
}

/**
 * ext irq9_5
 *
 *  External interrupt handler for irqs 9 through 5.
 *
 */
static void
ext_irq9_5(void)
{
    int index;

    ++ext_irq_counts.irq9_5;
    for (index = 5; index <= 9; ++index) {
        ext_irq_handler(index);
    }
}

/**
 * ext irq15_10
 *
 *  External interrupt handler for irqs 15 through 10.
 *
 */
static void
ext_irq15_10(void)
{
    int index;

    ++ext_irq_counts.irq15_10;
    for (index = 10; index <= 15; ++index) {
        ext_irq_handler(index);
    }
}

#else /* MYNEWT_VAL(MCU_STM32L0) */

/**
 * ext irq0_1
 *
 *  External interrupt handler for irqs 0 through 1.
 *
 */
static void
ext_irq0_1(void)
{
    int index;

    ++ext_irq_counts.irq0_1;
    for (index = 0; index <= 1; ++index) {
        ext_irq_handler(index);
    }
}

/**
 * ext irq2_3
 *
 *  External interrupt handler for irqs 2 through 3.
 *
 */
static void
ext_irq2_3(void)
{
    int index;

    ++ext_irq_counts.irq2_3;
    for (index = 2; index <= 3; ++index) {
        ext_irq_handler(index);
    }
}

/**
 * ext irq4_15
 *
 *  External interrupt handler for irqs 4 through 15.
 *
 */
static void
ext_irq4_15(void)
{
    int index;

    ++ext_irq_counts.irq4_15;
    for (index = 4; index <= 15; ++index) {
        ext_irq_handler(index);
    }
}

#endif /* MYNEWT_VAL(MCU_STM32L0) */

/**
 * hal gpio clk enable
 *
 * Enable the port peripheral clock
 *
 * @param port_idx
 */
static void
hal_gpio_clk_enable(uint32_t port_idx)
{
    switch (port_idx) {
#if defined GPIOA_BASE
    case 0:
        __HAL_RCC_GPIOA_CLK_ENABLE();
        break;
#endif
#if defined GPIOB_BASE
    case 1:
        __HAL_RCC_GPIOB_CLK_ENABLE();
        break;
#endif
#if defined GPIOC_BASE
    case 2:
        __HAL_RCC_GPIOC_CLK_ENABLE();
        break;
#endif
#if defined GPIOD_BASE
    case 3:
        __HAL_RCC_GPIOD_CLK_ENABLE();
        break;
#endif
#if defined GPIOE_BASE
    case 4:
        __HAL_RCC_GPIOE_CLK_ENABLE();
        break;
#endif
#if defined GPIOF_BASE
    case 5:
        __HAL_RCC_GPIOF_CLK_ENABLE();
        break;
#endif
#if defined GPIOG_BASE
    case 6:
        __HAL_RCC_GPIOG_CLK_ENABLE();
        break;
#endif
#if defined GPIOH_BASE
    case 7:
        __HAL_RCC_GPIOH_CLK_ENABLE();
        break;
#endif
#if defined GPIOI_BASE
    case 8:
        __HAL_RCC_GPIOI_CLK_ENABLE();
        break;
#endif
#if defined GPIOJ_BASE
    case 9:
        __HAL_RCC_GPIOJ_CLK_ENABLE();
        break;
#endif
#if defined GPIOK_BASE
    case 10:
        __HAL_RCC_GPIOK_CLK_ENABLE();
        break;
#endif
    default:
        assert(0);
        break;
    }
}

/**
 * hal gpio pin to irq
 *
 * Converts the logical pin number to the IRQ number associated with the
 * external interrupt for that particular GPIO.
 *
 * @param pin
 *
 * @return IRQn_Type
 */
static IRQn_Type
hal_gpio_pin_to_irq(int pin)
{
    int index;
    IRQn_Type irqn;

    index = MCU_GPIO_PIN_NUM(pin);

#if !MYNEWT_VAL(MCU_STM32L0)
    if (index <= 4) {
        irqn = EXTI0_IRQn + index;
    } else if (index <=  9) {
        irqn = EXTI9_5_IRQn;
    } else {
        irqn = EXTI15_10_IRQn;
    }
#else
    if (index <= 1) {
        irqn = EXTI0_1_IRQn;
    } else if (index <=  3) {
        irqn = EXTI2_3_IRQn;
    } else {
        irqn = EXTI4_15_IRQn;
    }
#endif

    return irqn;
}

#if MYNEWT_VAL(MCU_STM32F3)
#   define EXTI2_IRQn   EXTI2_TSC_IRQn
#endif

static void
hal_gpio_set_nvic(IRQn_Type irqn)
{
    uint32_t isr;

    switch (irqn) {
#if !MYNEWT_VAL(MCU_STM32L0)
    case EXTI0_IRQn:
        isr = (uint32_t)&ext_irq0;
        break;
    case EXTI1_IRQn:
        isr = (uint32_t)&ext_irq1;
        break;
#else /* MYNEWT_VAL(MCU_STM32L0) */
    case EXTI0_1_IRQn:
        isr = (uint32_t)&ext_irq0_1;
        break;
#endif

#if !MYNEWT_VAL(MCU_STM32L0)
    case EXTI2_IRQn:
        isr = (uint32_t)&ext_irq2;
        break;
    case EXTI3_IRQn:
        isr = (uint32_t)&ext_irq3;
        break;
#else /* MYNEWT_VAL(MCU_STM32L0) */
    case EXTI2_3_IRQn:
        isr = (uint32_t)&ext_irq2_3;
        break;
#endif

#if !MYNEWT_VAL(MCU_STM32L0)
    case EXTI4_IRQn:
        isr = (uint32_t)&ext_irq4;
        break;
    case EXTI9_5_IRQn:
        isr = (uint32_t)&ext_irq9_5;
        break;
    case EXTI15_10_IRQn:
        isr = (uint32_t)&ext_irq15_10;
        break;
#else /* MYNEWT_VAL(MCU_STM32L0) */
    case EXTI4_15_IRQn:
        isr = (uint32_t)&ext_irq4_15;
        break;
#endif

    default:
        assert(0);
        break;
    }

    /* Set isr in vector table if not yet set */
    if (NVIC_GetVector(irqn) != isr) {
        NVIC_SetVector(irqn, isr);
        NVIC_EnableIRQ(irqn);
    }
}

/**
 * hal gpio init
 *
 * Called to initialize a gpio.
 *
 * @param pin
 * @param cfg
 *
 * @return int
 */
int
hal_gpio_init_stm(int pin, GPIO_InitTypeDef *cfg)
{
    int port;
    uint32_t mcu_pin_mask;

    /* Is this a valid pin? */
    port = MCU_GPIO_PIN_PORT(pin);
    if (port >= HAL_GPIO_PORT_COUNT) {
        return -1;
    }

    mcu_pin_mask = GPIO_MASK(pin);
    cfg->Pin = mcu_pin_mask;

    /* Enable the GPIO clock */
    hal_gpio_clk_enable(port);

    /* Initialize pin as an input, setting proper mode */
    HAL_GPIO_Init(portmap[port], cfg);

    return 0;
}

/**
 * hal gpio deinit
 *
 * Called to deinitialize a gpio.
 *
 * @param pin
 * @param cfg
 *
 * @return int
 */
int
hal_gpio_deinit_stm(int pin, GPIO_InitTypeDef *cfg)
{
    int port;
    uint32_t mcu_pin_mask;

    /* Is this a valid pin? */
    port = MCU_GPIO_PIN_PORT(pin);
    if (port >= HAL_GPIO_PORT_COUNT) {
        return -1;
    }

    mcu_pin_mask = GPIO_MASK(pin);
    cfg->Pin = mcu_pin_mask;

    /* Initialize pin as an input, setting proper mode */
    HAL_GPIO_DeInit(portmap[port], cfg->Pin);

    return 0;
}

/**
 * gpio init in
 *
 * Initializes the specified pin as an input
 *
 * @param pin   Pin number to set as input
 * @param pull  pull type
 *
 * @return int  0: no error; -1 otherwise.
 */
int
hal_gpio_init_in(int pin, hal_gpio_pull_t pull)
{
    int rc;
    GPIO_InitTypeDef init_cfg;

    init_cfg.Mode = GPIO_MODE_INPUT;
    init_cfg.Pull = pull;

    rc = hal_gpio_init_stm(pin, &init_cfg);
    return rc;
}

/**
 * gpio init out
 *
 * Initialize the specified pin as an output, setting the pin to the specified
 * value.
 *
 * @param pin Pin number to set as output
 * @param val Value to set pin
 *
 * @return int  0: no error; -1 otherwise.
 */
int hal_gpio_init_out(int pin, int val)
{
    GPIO_InitTypeDef cfg;
    int port;

    /* Is this a valid pin? */
    port = MCU_GPIO_PIN_PORT(pin);
    if (port >= HAL_GPIO_PORT_COUNT) {
        return -1;
    }

    /* Enable the GPIO clock */
    hal_gpio_clk_enable(port);

    /* Write initial output value */
    hal_gpio_write(pin, val);

    cfg.Pin = GPIO_MASK(pin);
    cfg.Mode = GPIO_MODE_OUTPUT_PP;
    cfg.Pull = GPIO_NOPULL;
#if defined(GPIO_SPEED_FREQ_VERY_HIGH)
    cfg.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
#elif defined(GPIO_SPEED_HIGH)
    cfg.Speed = GPIO_SPEED_HIGH;
#else
    cfg.Speed = GPIO_SPEED_FREQ_HIGH;
#endif
#if !MYNEWT_VAL(MCU_STM32F1)
    cfg.Alternate = 0;
#endif

    /* Initialize pin as an output, setting proper mode */
    HAL_GPIO_Init(portmap[port], &cfg);

    return 0;
}

/**
 * gpio init af
 *
 * Configure the specified pin for AF.
 */
int
hal_gpio_init_af(int pin, uint8_t af_type, enum hal_gpio_pull pull, uint8_t od)
{
    GPIO_InitTypeDef gpio;

    if (!od) {
        gpio.Mode = GPIO_MODE_AF_PP;
    } else {
        gpio.Mode = GPIO_MODE_AF_OD;
    }
    gpio.Pull = pull;
#if defined(GPIO_SPEED_FREQ_VERY_HIGH)
    gpio.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
#elif defined(GPIO_SPEED_HIGH)
    gpio.Speed = GPIO_SPEED_HIGH;
#else
    gpio.Speed = GPIO_SPEED_FREQ_HIGH;
#endif
#if !MYNEWT_VAL(MCU_STM32F1)
    gpio.Alternate = af_type;
#endif

    return hal_gpio_init_stm(pin, &gpio);
}

/**
 * gpio write
 *
 * Write a value (either high or low) to the specified pin.
 *
 * @param pin Pin to set
 * @param val Value to set pin (0:low 1:high)
 */
void hal_gpio_write(int pin, int val)
{
    int port;
    uint32_t mcu_pin_mask;
    GPIO_PinState state;

    port = MCU_GPIO_PIN_PORT(pin);
    mcu_pin_mask = GPIO_MASK(pin);

    if (val) {
        state = GPIO_PIN_SET;
    } else {
        state = GPIO_PIN_RESET;
    }

    HAL_GPIO_WritePin(portmap[port], mcu_pin_mask, state);
}

/**
 * gpio read
 *
 * Reads the specified pin.
 *
 * @param pin Pin number to read
 *
 * @return int 0: low, 1: high
 */
int hal_gpio_read(int pin)
{
    int port;
    uint32_t mcu_pin_mask;

    port = MCU_GPIO_PIN_PORT(pin);
    mcu_pin_mask = GPIO_MASK(pin);
    return HAL_GPIO_ReadPin(portmap[port], mcu_pin_mask);
}

/**
 * gpio toggle
 *
 * Toggles the specified pin
 *
 * @param pin Pin number to toggle
 *
 * @return current pin state int 0: low 1 : high
 */
int hal_gpio_toggle(int pin)
{
    int pin_state = (hal_gpio_read(pin) != 1);
    hal_gpio_write(pin, pin_state);
    return pin_state;
}

/**
 * gpio irq init
 *
 * Initialize an external interrupt on a gpio pin
 *
 * @param pin       Pin number to enable gpio.
 * @param handler   Interrupt handler
 * @param arg       Argument to pass to interrupt handler
 * @param trig      Trigger mode of interrupt
 * @param pull      Push/pull mode of input.
 *
 * @return int
 */
int
hal_gpio_irq_init(int pin, hal_gpio_irq_handler_t handler, void *arg,
                  hal_gpio_irq_trig_t trig, hal_gpio_pull_t pull)
{
    int rc;
    int irqn;
    int index;
    uint32_t pin_mask;
    uint32_t mode;
    GPIO_InitTypeDef init_cfg;

    /* Configure the gpio for an external interrupt */
    rc = 0;
    switch (trig) {
    case HAL_GPIO_TRIG_NONE:
        rc = -1;
        break;
    case HAL_GPIO_TRIG_RISING:
        mode = GPIO_MODE_IT_RISING;
        break;
    case HAL_GPIO_TRIG_FALLING:
        mode = GPIO_MODE_IT_FALLING;
        break;
    case HAL_GPIO_TRIG_BOTH:
        mode = GPIO_MODE_IT_RISING_FALLING;
        break;
    case HAL_GPIO_TRIG_LOW:
        rc = -1;
        break;
    case HAL_GPIO_TRIG_HIGH:
        rc = -1;
        break;
    default:
        rc = -1;
        break;
    }

    /* Check to make sure no error has occurred */
    if (!rc) {
        /* Disable interrupt and clear any pending */
        hal_gpio_irq_disable(pin);
        pin_mask = GPIO_MASK(pin);
        __HAL_GPIO_EXTI_CLEAR_FLAG(pin_mask);

        /* Set the gpio irq handler */
        index = MCU_GPIO_PIN_NUM(pin);
        gpio_irq_handlers[index].isr = handler;
        gpio_irq_handlers[index].arg = arg;

        /* Configure the GPIO */
        init_cfg.Mode = mode;
        init_cfg.Pull = pull;
        rc = hal_gpio_init_stm(pin, &init_cfg);
        if (!rc) {
            /* Enable interrupt vector in NVIC */
            irqn = hal_gpio_pin_to_irq(pin);
            hal_gpio_set_nvic(irqn);
        }
    }

    return rc;
}

/**
 * gpio irq release
 *
 * No longer interrupt when something occurs on the pin. NOTE: this function
 * does not change the GPIO push/pull setting nor does it change the
 * SYSCFG EXTICR registers. It also does not disable the NVIC interrupt enable
 * setting for the irq.
 *
 * @param pin
 */
void
hal_gpio_irq_release(int pin)
{
    int index;
    uint32_t pin_mask;

    /* Disable the interrupt */
    hal_gpio_irq_disable(pin);

    /* Clear any pending interrupts */
    pin_mask = GPIO_MASK(pin);
    __HAL_GPIO_EXTI_CLEAR_FLAG(pin_mask);

    /* Clear out the irq handler */
    index = MCU_GPIO_PIN_NUM(pin);
    gpio_irq_handlers[index].arg = NULL;
    gpio_irq_handlers[index].isr = NULL;
}

/**
 * gpio irq enable
 *
 * Enable the irq on the specified pin
 *
 * @param pin
 */
void
hal_gpio_irq_enable(int pin)
{
    uint32_t ctx;
    uint32_t mask;

    mask = GPIO_MASK(pin);

    __HAL_DISABLE_INTERRUPTS(ctx);
#if MYNEWT_VAL(MCU_STM32L4)
    EXTI->IMR1 |= mask;
#else
    EXTI->IMR |= mask;
#endif
    __HAL_ENABLE_INTERRUPTS(ctx);
}

/**
 * gpio irq disable
 *
 *
 * @param pin
 */
void
hal_gpio_irq_disable(int pin)
{
    uint32_t ctx;
    uint32_t mask;

    mask = GPIO_MASK(pin);
    __HAL_DISABLE_INTERRUPTS(ctx);
#if MYNEWT_VAL(MCU_STM32L4)
    EXTI->IMR1 |= mask;
#else
    EXTI->IMR &= ~mask;
#endif
    __HAL_ENABLE_INTERRUPTS(ctx);
}
