/*******************************************************************************
* Project:      Amped'RF Bluetooth
* File name:    GKI_exti.c
* Description:  External Interrupt abstraction layer
*
* Copyright (c) 2013 Amped'RF Inc., AR Technology  All rights reserved.
*******************************************************************************/
#include "SDK_Common.h"
#include "GKI_lib.h"


#if defined(STM32F2xx) || defined(STM32F4xx)
IRQn_Type EXT_IRQn[16]={
    EXTI0_IRQn, EXTI1_IRQn, EXTI2_IRQn, EXTI3_IRQn, EXTI4_IRQn,
    EXTI9_5_IRQn, EXTI9_5_IRQn, EXTI9_5_IRQn, EXTI9_5_IRQn, EXTI9_5_IRQn,
    EXTI15_10_IRQn, EXTI15_10_IRQn, EXTI15_10_IRQn, EXTI15_10_IRQn, EXTI15_10_IRQn, EXTI15_10_IRQn};
#endif


//------------------------------------------------------------------------------
// GKI_exti_GenerateSWInterrupt
// Generates a Software interrupt.
//------------------------------------------------------------------------------
void GKI_exti_GenerateSWInterrupt(u32 EXTI_Line)
{
    EXTI_GenerateSWInterrupt(EXTI_Line);
}



//------------------------------------------------------------------------------
// GKI_exti_GpioEvent
// Enable GPIO Event interrupts.
//------------------------------------------------------------------------------
void GKI_GpioWakeupSet(u16 io, u8 trigger, uint8 type)
{
    EXTI_InitTypeDef EXTI_InitStruct;
    uint32 ExtLineMask;

    if (io!=IO_UNDEFINED)
    {
        ExtLineMask = _MASK(io);

        // Configure EXTI to a specific Port & Pin
#if defined(STM32F10x)
        GPIO_EXTILineConfig(_SOURCE(io), _PIN(io));
#elif defined(STM32F2xx) || defined(STM32F4xx)
        SYSCFG_EXTILineConfig(_SOURCE(io), _PIN(io));
#else
#warning No _EXTILineConfig definition
#endif

        // Setup EXTI Structure
        EXTI_StructInit(&EXTI_InitStruct);
        EXTI_InitStruct.EXTI_Mode           = (type == 0 ? EXTI_Mode_Event : EXTI_Mode_Interrupt);
        EXTI_InitStruct.EXTI_LineCmd        = ENABLE;
        EXTI_InitStruct.EXTI_Line           = ExtLineMask;
        EXTI_InitStruct.EXTI_Trigger        = trigger;
        EXTI_Init(&EXTI_InitStruct);
        EXTI_ClearITPendingBit(ExtLineMask);
    }
}


void GKI_exti_GpioEventEnable(u16 io, u8 trigger)
{
	GKI_GpioWakeupSet(io, trigger, 0);
}



//------------------------------------------------------------------------------
// GKI_exti_GpioEvent
// Enable GPIO Event interrupts.
//------------------------------------------------------------------------------
/*
void GKI_exti_GpioEventDisable(u16 io)
{
    EXTI_InitTypeDef EXTI_InitStruct;
    uint32 ExtLineMask;

    if (io!=IO_UNDEFINED)
    {
        ExtLineMask = _MASK(io);

        // Configure EXTI to a specific Port & Pin
#if defined(STM32F10x)
        GPIO_EXTILineConfig(_SOURCE(io), _PIN(io));
#elif defined(STM32F2xx) || defined(STM32F4xx)
        SYSCFG_EXTILineConfig(_SOURCE(io), _PIN(io));
#else
#warning No _EXTILineConfig definition
#endif

        // Setup EXTI Structure
        EXTI_StructInit(&EXTI_InitStruct);
        EXTI_InitStruct.EXTI_Mode           = EXTI_Mode_Event;
        EXTI_InitStruct.EXTI_LineCmd        = DISABLE;
        EXTI_InitStruct.EXTI_Line           = ExtLineMask;
        EXTI_InitStruct.EXTI_Trigger        = EXTI_Trigger_Falling;
        EXTI_Init(&EXTI_InitStruct);
        EXTI_ClearITPendingBit(ExtLineMask);
    }
}
*/



//------------------------------------------------------------------------------
// Interrupt
//------------------------------------------------------------------------------
typedef struct {
    u32 imr;
    u32 emr;
    u32 rtsr;
    u32 ftsr;
    u32 pr;
#if defined(xSTM32F2xx)
    u32 EXTICR[4];
#endif
} tExtReg;



//------------------------------------------------------------------------------
// Function Name  : TM_EXTI
// Description    : Enable/Disable/Initialize external interrupts
//------------------------------------------------------------------------------
void GKI_exti_Cmd(FunctionalState state)
{
    static tExtReg Ext;

    switch (state) {
    case ENABLE:
        // Save EXTI registers & clear
        Ext.imr  = EXTI->IMR;
        Ext.emr  = EXTI->EMR;
        Ext.rtsr = EXTI->RTSR;
        Ext.ftsr = EXTI->FTSR;
        Ext.pr   = EXTI->PR;
#if defined(xSTM32F2xx)
        for (u8 i=0; i<4; i++) {
            Ext.EXTICR[i] = SYSCFG->EXTICR[i];
        }
#endif
        EXTI_DeInit();

#ifndef TI2564
        // Setup wakeup pins
        GKI_exti_GpioEventEnable(IO_HCI_HOST_WAKE,  EXTI_Trigger_Rising);
#endif
#if !defined(BT24)
        GKI_exti_GpioEventEnable(IO_HCI_CTS, EXTI_Trigger_Falling);
#endif

        // Wake from customer defined GPIO
        GKI_exti_GpioEventEnable(io_HOST_WAKEUP, EXTI_Trigger_Rising_Falling);
#ifdef TI2564
        GKI_io_Config(IO_HCI_RTS, GKI_IO_OUT_PP);
        GKI_io_WriteBit(IO_HCI_RTS, 1);
#endif

#ifdef CUSTOM_MAIN_UART_WAKEUP
        GKI_exti_GpioEventEnable(IO_MAIN_RX, EXTI_Trigger_Rising_Falling);
#endif

        // Setup RTC Wakeup
//#if defined(STM32F2xx) || defined(STM32F4xx)
//        TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE);

//#else

		NVIC_InitTypeDef NVIC_InitStructure;

		EXTI_InitTypeDef EXTI_InitStructure;
		EXTI_ClearITPendingBit(EXTI_Line17);
		EXTI_InitStructure.EXTI_Line = EXTI_Line17;
		EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
		EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
		EXTI_InitStructure.EXTI_LineCmd = ENABLE;
		EXTI_Init(&EXTI_InitStructure);

		NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);
		NVIC_InitStructure.NVIC_IRQChannel = RTC_Alarm_IRQn;
		NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
		NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
		NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
		NVIC_Init(&NVIC_InitStructure);
//#endif
        break;


    case DISABLE:
        //GKI_exti_GpioEventDisable(TM_GPIO_HOST_WAKEUP);
#if defined(xSTM32F2xx)
        for (u8 i=0; i<4; i++) {
            SYSCFG->EXTICR[i] = Ext.EXTICR[i];
        }
#endif
        // Clear EXTI registers and restore them
        EXTI_DeInit();
        EXTI->IMR   = Ext.imr;
        EXTI->EMR   = Ext.emr;
        EXTI->RTSR  = Ext.rtsr;
        EXTI->FTSR  = Ext.ftsr;
		#ifdef TI2564
        GKI_io_WriteBit(IO_HCI_RTS, 0);//low rts,enable trans data
		GKI_io_Config(IO_HCI_CTS, GKI_IO_AF_IN);
		#endif
        break;
    }
}





//--------------------------------------------------------------
//