/**
  ******************************************************************************
  * @file    stm32f10x_it.c
  * @author  MCD Application Team
  * @version V1.0.0
  * @date    07/07/2010
  * @brief   Main and lcd driver Interrupt Service Routines.
  *          This file provides template for all exceptions handler and peripherals
  *          interrupt service routine.
  ******************************************************************************
  * @copy
  *
  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  *
  * <h2><center>&copy; COPYRIGHT 2010 STMicroelectronics</center></h2>
  */ 
/* Includes ------------------------------------------------------------------*/
#include "stm32f10x_it.h"
#include "main.h"
#include "lcd_driver.h"


/** @defgroup  STM32F10x_it
* @brief This file conatins the interrupt handlers for TFT-LCD driver
* @{
*/ 

/** @defgroup STM32F10x_it_Private_TypesDefinitions
* @{
*/ 
/**
* @}
*/ 


/** @defgroup STM32F10x_it_Private_Defines
* @{
*/ 
/**
* @}
*/ 


/** @defgroup STM32F10x_it_Private_Macros
* @{
*/ 
/**
* @}
*/ 


/** @defgroup STM32F10x_it_Private_Variables
* @{
*/
__IO uint16_t LCD_DisplayLines           = 0;
__IO uint8_t  SlideShowImageCounter      = 0;
__IO uint32_t backlight_factor = 0 ;
__IO uint8_t  NewDisplayFrame            = FALSE;
LCD_DisplayMode_Typedef LCD_DisplayMode  = LCD_BannerMode;


/**
* @}
*/ 


/** @defgroup STM32F10x_it_Private_FunctionPrototypes
* @{
*/ 
/**
* @}
*/ 


/** @defgroup STM32F10x_it_Private_Functions
* @{
*/ 


/******************************************************************************/
/*            Cortex-M3 Processor Exceptions Handlers                         */
/******************************************************************************/

/**
* @brief  NMI_Handler
*         This function handles NMI exception.
* @param  None
* @retval None
*/
void NMI_Handler(void)
{
}

/**
* @brief  HardFault_Handler
*         This function handles Hard Fault exception.
* @param  None
* @retval None
*/
void HardFault_Handler(void)
{
  /* Go to infinite loop when Hard Fault exception occurs */
  while (1)
  {
  }
}

/**
* @brief  MemManage_Handler
*         This function handles Memory Manage exception.
* @param  None
* @retval None
*/
void MemManage_Handler(void)
{
  /* Go to infinite loop when Memory Manage exception occurs */
  while (1)
  {
  }
}

/**
* @brief  BusFault_Handler
*         This function handles Bus Fault exception.
* @param  None
* @retval None
*/
void BusFault_Handler(void)
{
  /* Go to infinite loop when Bus Fault exception occurs */
  while (1)
  {
  }
}

/**
* @brief  UsageFault_Handler
*         This function handles Usage Fault exception.
* @param  None
* @retval None
*/
void UsageFault_Handler(void)
{
  /* Go to infinite loop when Usage Fault exception occurs */
  while (1)
  {
  }
}

/**
* @brief  SVC_Handler
*         This function handles SVCall exception.
* @param  None
* @retval None
*/
void SVC_Handler(void)
{
}

/**
* @brief  DebugMon_Handler
*         This function handles Debug Monitor exception.
* @param  None
* @retval None
*/
void DebugMon_Handler(void)
{
}

/**
* @brief  This function handles PendSVC exception.
* @param  None
* @retval None
*/
void PendSV_Handler(void)
{
}

/**
* @brief  SysTick_Handler
*         This function handles SysTick Handler.
* @param  None
* @retval None
*/
void SysTick_Handler(void)
{
  
  /* Decrement the TimingDelay variable */
  Decrement_TimingDelay();
  
}

/**
* @brief  DMA1_Channel1_IRQHandler
*         This function handles DMA1 Channel 1 interrupt request
* @param  None
* @retval None
*/
void DMA1_Channel1_IRQHandler(void)
{
  /* Set TFT_HSYNC High  */
  TFT_HSYNC_HIGH;  
  
  /* Check for start of frame : 
  Dummy data is sent in start of frame for 2 lines : Frame Front porch */     
  if(LCD_DisplayLines < LCD_FRAME_FRONT_PORCH)
  {  
    /* DMA Re-configuration for single line of LCD display with dummy data 0x00 */
    DMA1_Channel2->CCR &=((uint32_t)0xFFFFFFFE);       /* Disable DMA Channel */
    DMA1_Channel2->CNDTR = LCD_HORZ_LINE;               /* Load DMA Data Counter */
    DMA1_Channel2->CPAR = (uint32_t)DummyDisplayBuffer; /* Load DMA Source address*/
    DMA1_Channel2->CCR  |= ((uint32_t)0x00000001);      /* Enable DMA Channel */
  }      
  
  /* Valid data for single LCD frame */
  else if((LCD_DisplayLines >= LCD_FRAME_FRONT_PORCH)\
    && (LCD_DisplayLines < LCD_FRAME_BACK_PORCH_START))
  {
    
    /* DMA Re-configuration for single line of LCD display with valid data */
    DMA1_Channel2->CCR &=((uint32_t)0xFFFFFFFE);    /* Disable DMA Channel */
    DMA1_Channel2->CNDTR = LCD_HORZ_LINE;           /* Load DMA Data Counter */
    DMA1_Channel2->CPAR = (uint32_t)ImageSourceAddrCounter; /* Load DMA Source address*/
    DMA1_Channel2->CCR |= ((uint32_t)0x00000001);      /* Enable DMA Channel */
    
    /* Image source is of 16bit data width ,Hence for ach LCD line display
    Increment Image data source by (LCD_HORZ_LINE*2) = 320*2 =640 for QVGA */
    ImageSourceAddrCounter += IMG_SRC_LINE_SIZE;
    
  }
  
  /* Dummy data for single LCD frame back porch */
  else if(( LCD_DisplayLines >=LCD_FRAME_BACK_PORCH_START)\
    && (LCD_DisplayLines < LCD_FRAME_END))
  {    
    DMA1_Channel2->CCR  &=((uint32_t)0xFFFFFFFE);     /* Disable DMA Channel */
    DMA1_Channel2->CNDTR = LCD_HORZ_LINE;              /* Load DMA Data Counter */
    DMA1_Channel2->CPAR = (uint32_t)DummyDisplayBuffer;  /* Load DMA Source address */
    DMA1_Channel2->CCR |= ((uint32_t)0x00000001);        /* Enable DMA Channel */   
  }  
  
  /* Clear DMA Transfer complete interrupt pending bit*/
   DMA1->IFCR = DMA1_IT_TC1;
}

/**
* @brief  DMA1_Channel2_IRQHandler
*         This function handles DMA1 Channel 2 interrupt request.
* @param  None
* @retval None
*/
void DMA1_Channel2_IRQHandler(void)
{
  /* Check for end of frame : 
  Dummy data is sent in end of frame for 4 lines : Frame Back porch */     
  if(LCD_DisplayLines < LCD_FRAME_END)
  {  
    
    DMA1_Channel3->CCR &=((uint32_t)0xFFFFFFFE);     /* Disable DMA Channel */
    DMA1_Channel3->CNDTR = LCD_LINE_BACK_PORCH;      /* Load DMA Data Counter */
    DMA1_Channel3->CCR |= ((uint32_t)0x00000001);    /* Enable DMA Channel */
    LCD_DisplayLines++;       
  } 
  
  /* Clear DMA Transfer complete interrupt pending bit */
   DMA1->IFCR = DMA1_IT_TC2;
}

/**
* @brief  DMA1_Channel3_IRQHandler
*         This function handles DMA1 Channel 3 interrupt request.
* @param  None
* @retval None
*/
void DMA1_Channel3_IRQHandler(void)
{
 
  /* Set TFT_HSYNC Low  */
  TFT_HSYNC_LOW;
  
  /* Check for start of frame : 
  Dummy data is sent in start of frame for 2 lines : Frame Front porch */    
  if(LCD_DisplayLines < LCD_FRAME_FRONT_PORCH)
  {  
    
    /* Start of new line */  
    /* DMA Re-configuration for dummy data pixels for single dummy data line */
    DMA1_Channel1->CCR  &=((uint32_t)0xFFFFFFFE);    /* Disable DMA Channel */
    DMA1_Channel1->CNDTR = LCD_LINE_FRONT_PORCH;     /* Load DMA Data Counter */
    DMA1_Channel1->CCR  |= ((uint32_t)0x00000001);    /* Enable DMA Channel */
  }
  
  /* Dummy data pixels for each Valid data line */ 
  else if((LCD_DisplayLines >= LCD_FRAME_FRONT_PORCH)\
    && (LCD_DisplayLines < LCD_FRAME_BACK_PORCH_START))
  {
   /* Set  TFT_VSYNC  High  */
    TFT_VSYNC_HIGH;
    
    /* Start of new line */    
    /* DMA Re-configuration for dummy data pixels for single line */
    DMA1_Channel1->CCR  &= ((uint32_t)0xFFFFFFFE);    /* Disable DMA Channel */
    DMA1_Channel1->CNDTR = LCD_LINE_FRONT_PORCH;      /* Load DMA Data Counter */
    DMA1_Channel1->CCR  |= ((uint32_t)0x00000001);    /* Enable DMA Channel */
    
  }
  
  /* Dummy data pixels for each dummy data line  in frame back porch*/ 
  else if(( LCD_DisplayLines >=LCD_FRAME_BACK_PORCH_START) \
    && (LCD_DisplayLines < LCD_FRAME_END))
  {
    /* Start of new line */    
    /* DMA Reconfiguration for dummy data pixels for single line */
    DMA1_Channel1->CCR  &= ((uint32_t)0xFFFFFFFE);   /* Disable DMA Channel */
    DMA1_Channel1->CNDTR = LCD_LINE_FRONT_PORCH;     /* Load DMA Data Counter */
    DMA1_Channel1->CCR  |= ((uint32_t)0x00000001);   /* Enable DMA Channel */
    
  }  
  else if(LCD_DisplayLines == LCD_FRAME_END)
  {
    
    /* Start of new line */
    TFT_HSYNC_LOW;
    TFT_VSYNC_LOW;  
    
    /* If ADC value changes, configure new PWM output for 
     LED backlight driver */    
    /* Set timer compare register for a new dutycycle */
    if((ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)) != RESET)
    {
     backlight_factor  = (uint32_t)(0x0FFF - ADC1->DR);
     backlight_factor *= LCD_BL_TIMER_PERIOD;
     TIM4->CCR1       = (uint16_t)(backlight_factor/ 0x0FFF); 

    }
   
    /*  Allow new frame update */
    NewDisplayFrame  = TRUE;
  }
  
   /* Clear DMA Transfer complete interrupt pending bit */
   DMA1->IFCR = DMA1_IT_TC3;

}

/**
* @brief  DMA2_Channel1_IRQHandler
*         This function handles DMA2 Channel 1 interrupt request.
* @param  None
* @retval None
*/
void DMA2_Channel1_IRQHandler(void)
{
  /* Enable DMA2 channel2 */ 
  DMAComplete = TRUE;   
  
  /* Clear DMA Transfer complete interrupt pending bit*/
  DMA2->IFCR = DMA2_IT_TC1;
  
}

/**
* @brief  DMA2_Channel2_IRQHandler
*         This function handles DMA2 Channel 2 interrupt request.
* @param  None
* @retval None
*/
void DMA2_Channel2_IRQHandler(void)
{
  /* Clear DMA Transfer complete interrupt */
  DMA2->IFCR = DMA2_IT_TC2; 
  
}

/**
* @brief  TIM3_IRQHandler
*         This function handles TIM3 Channel1 interrupt request.
* @param  None
* @retval None
*/                             
void TIM3_IRQHandler(void)
{
  __IO uint16_t itstatus = 0x0, itenable = 0x0;
 GPIOB-> BSRR = GPIO_Pin_12; 
  /* This interrupt is used to manage the display frame rate */  
 
  /* Check for Timer2 update interrupt */
   itstatus = TIM3->SR & TIM_IT_Update;  
   itenable = TIM3->DIER & TIM_IT_Update;
 
  /* if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)*/
  if ((itstatus != (uint16_t)RESET) && (itenable != (uint16_t)RESET))
  {      
    /* Display new Frame */
    if(NewDisplayFrame == TRUE) 
    {  
      /* Reset Display line counter when one frame is completed */
      LCD_DisplayLines = 0;      
      
      /* LCD Display Banner Display mode -------------------------------------*/
      if( LCD_DisplayMode == LCD_BannerMode)
      {  
        /* Banner display is done using two image buffers in SRAM .
        When image is display from SRAM Buffer 1, image on SRAM buffer 2 
        is refreshed for next display */
        
        if((NOR_ImageIndex & 0x01) == 0x01)
        {   
          /* Display from SRAM buffer 1 and update SRAM buffer 2 */
          ImageSourceAddress = SRAM_IMAGE1;      
          CopyNewImageToExtSRAM(NORImageFileAddrMap[NOR_ImageIndex],SRAM_IMAGE2_ADDR);
        }
        else
        {
          /* Display from SRAM buffer 2 and update SRAM buffer 1*/
          ImageSourceAddress = SRAM_IMAGE2;      
          CopyNewImageToExtSRAM(NORImageFileAddrMap[NOR_ImageIndex],SRAM_IMAGE1_ADDR);     
        }     
        
        /* Increment the slide number */
        NOR_ImageIndex++;       
        
        if(NOR_ImageIndex >= LCD_BANNER_IMAGES)
        {
          NOR_ImageIndex = 2;          
        }      
      }
      
      /* Start New frame display -------------------------------------------- */
      
      /* Reset the new frame display */
      NewDisplayFrame = FALSE;
      
      /* Reset Image Source Address */     
      ImageSourceAddrCounter = ImageSourceAddress;        
      
      /* start the next frame display      
      Dummy data is sent in start of frame for 2 lines : Frame Front porch */         
      /* DMA Re-configuration for dummy data pixels for single dummy data line */
      DMA1_Channel1->CCR &=((uint32_t)0xFFFFFFFE);      /* Disable DMA Channel */
      DMA1_Channel1->CNDTR = LCD_LINE_FRONT_PORCH;      /* Load DMA Data Counter */
      DMA1_Channel1->CPAR = (uint32_t)DummyDisplayBuffer; /* Load DMA source address */
      DMA1_Channel1->CCR |= ((uint32_t)0x00000001);      /* Enable DMA Channel */
      
    }
  }  
  
  GPIOB-> BRR = GPIO_Pin_12; 
  /* Clear TIM3 updateinterrupt */
  TIM3->SR = (uint16_t)~TIM_IT_Update;
}

/**
* @brief  TIM2_IRQHandler
*         This function handles TIM2 Channel 1 interrupt request.
* @param  None
* @retval None
*/                             
void TIM2_IRQHandler(void)
{
  __IO uint16_t itstatus = 0x0, itenable = 0x0;
  
   /* This interrupt is used to manage the display image in SlideShow mode  */  
   /* Check for Timer2 update interrupt */
  itstatus = TIM2->SR & TIM_IT_Update;  
  itenable = TIM2->DIER & TIM_IT_Update;
  if ((itstatus != (uint16_t)RESET) && (itenable != (uint16_t)RESET))
  {
    /* Increment Slide Show image counter to move to the next image for display */
    SlideShowImageCounter++;
    
    /* Reset the Slide Show image counter if it has reached the last image for display */
    if(SlideShowImageCounter == MAX_SLIDESHOW_IMAGE_COUNT)      
    {
      SlideShowImageCounter = 0;
     ImageSourceAddress = SRAM_IMAGE1;    
    }
    else
    {
      ImageSourceAddress = SRAM_IMAGE2;      
    } 
  } 
    
  /* Clear TIM2 updateinterrupt */
  TIM2->SR = (uint16_t)~TIM_IT_Update;
  
}

/**
* @brief  EXTI9_5_IRQHandler
*         This function handles External lines interrupt request.
* @param  None
* @retval None
*/  
void EXTI9_5_IRQHandler(void)
{
  
  if (((EXTI->PR & KEY_BUTTON_EXTI_LINE) != (uint32_t)RESET))
  {
    
    if(LCD_DisplayMode == LCD_BannerMode)
    {
      /* Switch  LCD Display mode between Danner and SlideShow */ 
      LCD_DisplayMode = LCD_SlideShowMode;
      
      /* New images has to be loaded for SlideShow display mode */
      /* Timer 3 control disable as images are not availables */
      TIM3->CR1 &= (uint16_t)0x03FE;  
      
      /* Copy SlideShow images to SRAM buffer for display */
      CopyNewImageToExtSRAM(NORImageFileAddrMap[0],SRAM_IMAGE1_ADDR);
      while(DMAComplete == FALSE)
      {
      } 
      CopyNewImageToExtSRAM(NORImageFileAddrMap[1],SRAM_IMAGE2_ADDR);       
      
      /* Set Image source address for display */
      ImageSourceAddress = SRAM_IMAGE1;        
      
      /* Enable the SlideShow TIM2 Counter in SlideShow display mode */         
      TIM2->CR1 |=(uint16_t) 0x0001;
      
      /* New images are available, enable TIM3  */
      TIM3->CR1 |=(uint16_t) 0x0001;
    }
    else
    {
      /* Switch  LCD Display mode between banner and slideshow */ 
      LCD_DisplayMode = LCD_BannerMode;         
      
     /* In Banner display mode ; TIM2 is not used since image is updated 
       on each frame refresh */ 
      TIM2->CR1 &= (uint16_t)0x03FE;           
    }
    
    /* Clear the Key Button EXTI line pending bit */    
     EXTI->PR = KEY_BUTTON_EXTI_LINE;
  }
  
  
}  

/**
* @}
*/ 

/**
* @}
*/ 

/**
* @}
*/


/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
