/**
  **********************************************************************************
  * @file    dcmi_hal.c
  * @author  Product application department
  * @version V1.0
  * @date    2020.05.25
  * @brief   DCMI模块HAL层驱动.
  *
  @verbatim
  ===================================================================================
                                  ##### 更新 #####
  ===================================================================================
  [..] 更新时间:
  [..] 更新人:
  [..] 更新内容:
        1. nothing.
  @endverbatim
*/

#include "dcmi_hal.h"

/*** 全局变量定义 ***************************************************************/
/** @
  * @{volatile
  */
/** @ 
  * @}
  */
/** @ 
  * @{static
  */
  static DCMI_HandleTypeDef *g_hdcmi;
/** @ 
  * @}
  */
/*** 常量定义 *******************************************************************/
/** @
  * @{const
  */
/** @ 
  * @}
  */

/*** 函数定义 *******************************************************************/

/**
  *@brief DCMI:注册寄存器的回调函数
  *
  *@param[in] hdcmi DCMI句柄
  *@param[in] callback:回调函数实例
  *@param[in] index:回调函数类别
  *@return
  *- 0 :成功;
  *- 1 :失败;
  */
static uint8_t HAL_DCMI_ConfigCallbackRegistry(DCMI_HandleTypeDef *hdcmi,
		                                            dcmi_callback_t callback,
                                                uint8_t           index)
{
	(void)index;
	hdcmi->callback = callback;
	return 0;
}

/**
  *@brief DCMI:中断处理函数
  *
  *@param[in] 
  *- NONE
  *@param[out]
  *- NONE
  *@return NONE
  */
void __weak HAL_DCMI_IRQHandler(void)
{
	 
	if(g_hdcmi->callback)
	{
		g_hdcmi->callback((void *)g_hdcmi);
		return;
	}
}
#define readl(addr)		(*(volatile unsigned long *)(addr))
#define writel(addr,value) (*(volatile unsigned long *)(addr))=((unsigned long)(value))
	
/**
  *@brief DCMI:中断回调处理函数
  *
  *@param[in] 
  *- NONE
  *@param[out]
  *- NONE
  *@return NONE
  */
void HAL_DCMI_Callback(void)
{
	uint32_t ris_bak;
	uint32_t line_num;
	uint32_t mis_bak;
	
	ris_bak = readl(0x40053000 + 0x0008);			//RIS
	mis_bak = readl(0x40053000 + 0x0010);			//MIS
	
	if(ris_bak & mis_bak)
	{
		writel(0x40053000 + 0x0014, mis_bak);

		if(mis_bak & 0x10)			//line interrupt.
		{
			printf("line_interrupt\n"); 
		}
		
		if(mis_bak & 0x80)			//gray interrupt.
		{
		 
			printf("Gray_interrupt\n");
			 
		}
	
		if(mis_bak & 0x400)			//specific line interrupt.
		{		
			printf("specific line interrupt!\n");			
		}
		if(mis_bak & 0x01)			//frame interrupt.
		{	 
			printf("frame interrupt\n" );

		}
	}
	
}	

 /**
  *@brief 根据DCMI_HandleTypeDef指定的参数初始化DCMI模块,并初始化相关handle.
  *
  *@param[in] hdcmi 指向DCMI_HandleTypeDef结构体的指针,此结构体包含了DCMI模块的配置信息;
  *@retval @ref HAL_StatusTypeDef
  */
HAL_StatusTypeDef HAL_DCMI_Init(DCMI_HandleTypeDef *hdcmi)
{
    if(hdcmi->State == HAL_DCMI_STATE_RESET)
    {
        //HAL_I2C_MspInit(hi2c);
    }

    hdcmi->State = HAL_DCMI_STATE_BUSY;

		if(hdcmi->Init.EnableIE == ENABLE)
	  {
	    g_hdcmi = hdcmi;
      HAL_DCMI_ConfigCallbackRegistry(hdcmi,HAL_DCMI_Callback,0);
	  }

    /*初始化硬件层相关*/
    DRV_DCMI_Init(hdcmi->Instance, &hdcmi->Init);

    hdcmi->ErrorCode = HAL_DCMI_ERROR_NONE;
		
    /*状态更改为READY*/
    hdcmi->State = HAL_DCMI_STATE_READY;

    return(HAL_OK);
}

 /**
  *@brief 从设备读取数据
  *
  *@param[in] hdcmi 指向DCMI_HandleTypeDef结构体的指针,此结构体包含了DCMI模块的配置信息;
  *@retval @ref HAL_StatusTypeDef
  */	
HAL_StatusTypeDef HAL_DCMI_Getgray(DCMI_HandleTypeDef *hdcmi)
{
  
	DRV_DCMI_Getgray(hdcmi->Instance, &hdcmi->Init);
	
	return(HAL_OK);
	
}
