TMC32_QJB/Camera/camara_main.c

667 lines
20 KiB
C
Raw Normal View History

2026-04-30 08:23:12 +00:00
/**
******************************************************************************
* @file DCMI_Com.c
* @author TMC Terminal Team
* @version V1.0.0
* @date 06/21/2018
* @brief DCMI module.
*
******************************************************************************
*
* 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, TMC 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 2016 TMC</center></h2>
******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "global.h"
volatile uint8_t gDCMICaptureFlag = 0;
DCMI_HandleTypeDef gHandleDCMI;
LLI_StructTypeDef dcmi_lli[37];
DMA_HandleTypeDef gHandleDMA;
Camera_Info gciCameraInfo;
//extern uint16_t Key_Action();
//extern uint8_t Key_Active(void);
extern uint8_t gKeyAction;
/*DCMI<4D><49><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD><D8B5><EFBFBD><EFBFBD><EFBFBD>*/
void TMC_DCMI_CpltCallback(DCMI_HandleTypeDef *hdcmi)
{
/*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ*/
gDCMICaptureFlag = 1;
// DMA_ClearITPendingBit(DMA_IT_TC7);
DMA_Cmd(hdcmi->DMA_Handle->Instance, DISABLE);
DCMI_CaptureCmd(DISABLE);/*<2A>رղ<D8B1><D5B2><EFBFBD>*/
}
void TMC_DCMI_ErrorCallback(DCMI_HandleTypeDef *hdcmi)
{
//while(1);
// ResetChip(6);
// JJJ_Prompt("TMC_DCMI_ErrorCallback\r\n");
}
/**
* @brief DMA SPI half transmit process complete callback.
* @param hdma pointer to a DMA_HandleTypeDef structure that contains
* the configuration information for the specified DMA module.
* @retval None
*/
static void TMC_DCMI_DMATransmitCplt(DMA_HandleTypeDef *hdma)
{
DCMI_HandleTypeDef *hdcmi = (DCMI_HandleTypeDef *)((DMA_HandleTypeDef *)hdma)->Parent;
hdcmi->State = HAL_DCMI_STATE_READY;
hdcmi->ErrorCode = HAL_DCMI_ERROR_NONE;
DCMI_Cmd(DISABLE);
TMC_DCMI_CpltCallback(hdcmi);
}
/**
* @brief DMA DCMI communication error callback.
* @param hdma pointer to a DMA_HandleTypeDef structure that contains
* the configuration information for the specified DMA module.
* @retval None
*/
static void TMC_DCMI_DMAError(DMA_HandleTypeDef *hdma)
{
DCMI_HandleTypeDef* hdcmi = (DCMI_HandleTypeDef* )((DMA_HandleTypeDef* )hdma)->Parent;
hdcmi->State = HAL_DCMI_STATE_ERROR;
hdcmi->ErrorCode = HAL_DCMI_ERROR_DMA;
DCMI_Cmd(DISABLE);
TMC_DCMI_ErrorCallback(hdcmi);
}
/**
* @brief Returns the DMA channel number
* @param[in] hdma: pointer to a DMA_HandleTypeDef structure that contains
* the configuration information for the specified DMA Stream.
* @retval DMA channel number
*/
static uint32_t DMA_CalcBitShift(DMA_HandleTypeDef *hdma)
{
uint32_t channel_number = (((uint32_t)hdma->Instance & 0xFFU)) / 32U;
return channel_number;
}
/**
* @brief Initializes the DCMI according to the specified
* parameters in the DCMI_InitTypeDef and create the associated handle.
* @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains
* the configuration information for DCMI.
* @retval HAL status
*/
TMC_StatusTypeDef TMC_DCMI_Init(DCMI_HandleTypeDef *hdcmi)
{
/* Check the DCMI peripheral state */
if(hdcmi == NULL)
{
return TMC_ERROR;
}
if(hdcmi->State == HAL_DCMI_STATE_RESET)
{
/* Allocate lock resource and initialize it */
hdcmi->Lock = HAL_UNLOCKED;
/* Init the low level hardware */
TMC_DCMI_MspInit(hdcmi);
}
/* Change the DCMI state */
hdcmi->State = HAL_DCMI_STATE_BUSY;
DCMI_Init(&hdcmi->Init);
/* Enable the Line, Vsync, Error and Overrun interrupts */
DCMI_ITConfig(DCMI_IT_LINE_MIS | DCMI_IT_VSYNC_MIS | DCMI_IT_ERR_MIS | DCMI_IT_OVR_MIS | DCMI_IT_FRAME_MIS, DISABLE);
/* Update error code */
hdcmi->ErrorCode = HAL_DCMI_ERROR_NONE;
/* Initialize the DCMI state*/
hdcmi->State = HAL_DCMI_STATE_READY;
return TMC_OK;
}
/**
* @brief Enables DCMI DMA request and enables DCMI capture
* @param hdcmi pointer to a DCMI_HandleTypeDef structure that contains
* the configuration information for DCMI.
* @param DCMI_Mode DCMI capture mode snapshot or continuous grab.This parameter can be a value of @ref DCMI_Capture_Mode
* @param LLI the NEXT Link Address
* @param pData The destination memory Buffer address (LCD Frame buffer).
* @param Length The length of capture to be transferred.
* @retval HAL status
*/
TMC_StatusTypeDef TMC_DCMI_Start_DMA(DCMI_HandleTypeDef *hdcmi, uint32_t DCMI_Mode, uint32_t LLI, uint32_t pData, uint32_t Length)
{
/* Check the DCMI peripheral state */
if(hdcmi == NULL)
{
return TMC_ERROR;
}
if((hdcmi->State == HAL_DCMI_STATE_RESET) || (hdcmi->State == HAL_DCMI_STATE_BUSY))
{
return TMC_ERROR;
}
__HAL_LOCK(hdcmi);
hdcmi->State = HAL_DCMI_STATE_BUSY;
hdcmi->ErrorCode = HAL_DCMI_ERROR_NONE;
hdcmi->pBuffPtr = pData;
hdcmi->XferSize = 0;
hdcmi->XferCount = 0;
DCMI_ConfigCaptureMode(DCMI_Mode);
DCMI_ITConfig(DCMI_IT_LINE_MIS | DCMI_IT_VSYNC_MIS | DCMI_IT_ERR_MIS | DCMI_IT_OVR_MIS | DCMI_IT_FRAME_MIS, DISABLE);
DCMI_ConfigDMA(ENABLE);
/* Set the SPI TxDMA Half transfer complete callback */
hdcmi->DMA_Handle->XferCpltCallback = TMC_DCMI_DMATransmitCplt;
/* Set the DMA error callback */
hdcmi->DMA_Handle->XferErrorCallback = TMC_DCMI_DMAError;
/* Set the DMA AbortCpltCallback */
hdcmi->DMA_Handle->XferAbortCallback = NULL;
DMA_SetChainListAddress(hdcmi->DMA_Handle->Instance, LLI);
TMC_DMA_Start_IT(hdcmi->DMA_Handle, (uint32_t)(&hdcmi->Instance->DR), (uint32_t)pData, Length);
__HAL_UNLOCK(hdcmi);
// if(DCMI_Mode == DCMI_CAPTURE_CONTINUOUS_GRAB)
// {
// DCMI_ITConfig(DCMI_IT_FRAME_MIS,ENABLE); //ʹ<><CAB9>֡<EFBFBD>ж<EFBFBD>
// NVIC_ClearPendingIRQ(DCMI_IRQn);
// NVIC_EnableIRQ(DCMI_IRQn);
// }
DCMI_Cmd(ENABLE);
return TMC_OK;
}
/**
* @brief Initialize the DMA according to the specified
* parameters in the DMA_InitTypeDef and create the associated handle.
* @param[in] hdma: Pointer to a DMA_HandleTypeDef structure that contains
* the configuration information for the specified DMA Stream.
* @retval TMC status
*/
TMC_StatusTypeDef TMC_DMA_Init(DMA_HandleTypeDef *hdma)
{
uint32_t tickstart = TMC_GetTick();
/* Check the DMA peripheral state */
if(hdma == NULL)
{
return TMC_ERROR;
}
/* Allocate lock resource */
__HAL_UNLOCK(hdma);
/* Change DMA peripheral state */
hdma->State = TMC_DMA_STATE_BUSY;
/* Disable the peripheral */
DMA_Cmd(hdma->Instance, DISABLE);
/* Check if the DMA channel is effectively disabled */
while(DMA_GetCmdStatus(hdma->Instance) != RESET)
{
// /* Check for the Timeout */
if((TMC_GetTick() - tickstart ) > TMC_TIMEOUT_DMA_ABORT)
{
// /* Update error code */
hdma->ErrorCode = TMC_DMA_ERROR_TIMEOUT;
// /* Process Unlocked */
__HAL_UNLOCK(hdma);
// /* Change the DMA state */
hdma->State = TMC_DMA_STATE_TIMEOUT;
return TMC_TIMEOUT;
}
}
//-------------jjj2022-07-17
/* init the DMA channel */
DMA_Init(hdma->Instance, &hdma->Init);
/* Initialize StreamIndex parameters to be used */
hdma->StreamIndex = DMA_CalcBitShift(hdma);
/* Clear all interrupt flags */
DMA_ClearITPendingBit(DMA_IT_TC_OFFS << hdma->StreamIndex);
DMA_ClearITPendingBit(DMA_IT_ERR_OFFS << hdma->StreamIndex);
/* Initialize the error code */
hdma->ErrorCode = TMC_DMA_ERROR_NONE;
/* Initialize the DMA state */
hdma->State = TMC_DMA_STATE_READY;
return TMC_OK;
}
/**
* @brief DeInitializes the DMA peripheral
* @param[in] hdma: pointer to a DMA_HandleTypeDef structure that contains
* the configuration information for the specified DMA Stream.
* @retval TMC status
*/
TMC_StatusTypeDef TMC_DMA_DeInit(DMA_HandleTypeDef *hdma)
{
/* Check the DMA peripheral state */
if(hdma == NULL)
{
return TMC_ERROR;
}
/* Check the DMA peripheral state */
if(hdma->State == TMC_DMA_STATE_BUSY)
{
/* Return error status */
return TMC_BUSY;
}
/* Reset DMA channel register */
DMA_DeInit(hdma->Instance);
/* Initialize the error code */
hdma->ErrorCode = TMC_DMA_ERROR_NONE;
/* Initialize the DMA state */
hdma->State = TMC_DMA_STATE_RESET;
/* Release Lock */
__HAL_UNLOCK(hdma);
return TMC_OK;
}
/**
* @brief Start the DMA Transfer with interrupt enabled.
* @param hdma pointer to a DMA_HandleTypeDef structure that contains
* the configuration information for the specified DMA Stream.
* @param SrcAddress The source memory Buffer address
* @param DstAddress The destination memory Buffer address
* @param DataLength The length of data to be transferred from source to destination
* @retval TMC status
*/
TMC_StatusTypeDef TMC_DMA_Start_IT(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
{
TMC_StatusTypeDef status = TMC_OK;
/* Process locked */
__HAL_LOCK(hdma);
if(TMC_DMA_STATE_READY == hdma->State)
{
/* Change DMA peripheral state */
hdma->State = TMC_DMA_STATE_BUSY;
/* Initialize the error code */
hdma->ErrorCode = TMC_DMA_ERROR_NONE;
/* Configure the source, destination address and the data length */
DMA_SetAddress(hdma->Instance, SrcAddress, DstAddress, DataLength);
/* Clear all interrupt flags at correct offset within the register */
DMA_ClearITPendingBit(DMA_IT_TC_OFFS << hdma->StreamIndex);
DMA_ClearITPendingBit(DMA_IT_ERR_OFFS << hdma->StreamIndex);
/* Enable Common interrupts*/
DMA_ITConfig(hdma->Instance, DMA_IT_TC, ENABLE);
DMA_ITConfig(hdma->Instance, DMA_IT_ERR, ENABLE);
/* Enable the Peripheral */
DMA_Cmd(hdma->Instance, ENABLE);
}
else
{
/* Process unlocked */
__HAL_UNLOCK(hdma);
/* Return error status */
status = TMC_BUSY;
}
return status;
}
/**
* @brief Aborts the DMA Transfer in Interrupt mode.
* @param hdma pointer to a DMA_HandleTypeDef structure that contains
* the configuration information for the specified DMA Stream.
* @retval TMC status
*/
TMC_StatusTypeDef TMC_DMA_Abort_IT(DMA_HandleTypeDef *hdma)
{
if(hdma->State != TMC_DMA_STATE_BUSY)
{
hdma->ErrorCode = TMC_DMA_ERROR_NO_XFER;
return TMC_ERROR;
}
else
{
/* Set Abort State */
hdma->State = TMC_DMA_STATE_ABORT;
/* Disable the stream */
DMA_Cmd(hdma->Instance, DISABLE);
}
return TMC_OK;
}
/**
* @brief Handles DMA interrupt request.
* @param hdma: pointer to a DMA_HandleTypeDef structure that contains
* the configuration information for the specified DMA Stream.
* @retval None
*/
void TMC_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
{
uint32_t complete_sts, error_sts;
__IO uint32_t count = 0U;
uint32_t timeout = SystemCoreClock / 9600U;
/* calculate DMA base and stream number */
complete_sts = DMA_IT_TC_OFFS << hdma->StreamIndex;
error_sts = DMA_IT_ERR_OFFS << hdma->StreamIndex;
/* Transfer Error Interrupt management ***************************************/
if(DMA_GetITStatus(error_sts) != RESET)
{
if(DMA_GetFlagStatus(error_sts) != RESET)
{
/* Disable the transfer error interrupt */
DMA_ITConfig(hdma->Instance, DMA_IT_ERR, DISABLE);
/* Clear the transfer error flag */
DMA_ClearITPendingBit(error_sts);
/* Update error code */
hdma->ErrorCode |= TMC_DMA_ERROR_TE;
}
}
/* Transfer Complete Interrupt management ***********************************/
if(DMA_GetITStatus(complete_sts) != RESET)
{
if(DMA_GetFlagStatus(complete_sts) != RESET)
{
/* Clear the transfer complete flag */
DMA_ClearITPendingBit(complete_sts);
if(TMC_DMA_STATE_ABORT == hdma->State)
{
/* Disable all the transfer interrupts */
DMA_ITConfig(hdma->Instance, DMA_IT_TC, DISABLE);
DMA_ITConfig(hdma->Instance, DMA_IT_ERR, DISABLE);
/* Clear all interrupt flags at correct offset within the register */
DMA_ClearITPendingBit(complete_sts);
DMA_ClearITPendingBit(error_sts);
/* Process Unlocked */
__HAL_UNLOCK(hdma);
/* Change the DMA state */
hdma->State = TMC_DMA_STATE_READY;
if(hdma->XferAbortCallback != NULL)
{
hdma->XferAbortCallback(hdma);
}
return;
}
/* Disable the transfer complete interrupt if the DMA mode is not CIRCULAR */
/* Disable the transfer complete interrupt */
DMA_ITConfig(hdma->Instance, DMA_IT_TC, DISABLE);
/* Process Unlocked */
__HAL_UNLOCK(hdma);
/* Change the DMA state */
hdma->State = TMC_DMA_STATE_READY;
if(hdma->XferCpltCallback != NULL)
{
/* Transfer complete callback */
hdma->XferCpltCallback(hdma);
}
}
}
/* manage error case */
if(hdma->ErrorCode != TMC_DMA_ERROR_NONE)
{
if((hdma->ErrorCode & TMC_DMA_ERROR_TE) != RESET)
{
hdma->State = TMC_DMA_STATE_ABORT;
/* Disable the stream */
DMA_Cmd(hdma->Instance, DISABLE);
do
{
if(++count > timeout)
{
break;
}
}
while(DMA_GetCmdStatus(hdma->Instance) != RESET);
/* Process Unlocked */
__HAL_UNLOCK(hdma);
/* Change the DMA state */
hdma->State = TMC_DMA_STATE_READY;
}
if(hdma->XferErrorCallback != NULL)
{
/* Transfer error callback */
hdma->XferErrorCallback(hdma);
}
}
}
/**
* @brief DCMI MSP Init.
* @param[in] hdcmi: pointer to a DCMI_HandleTypeDef structure that contains
* the configuration information for the specified DCMI module.
* @retval None
*/
void TMC_DCMI_MspInit(DCMI_HandleTypeDef *hdcmi)
{
RCC_APB3PeriphClockCmd(RCC_APB3Periph_GPIO, ENABLE);
RCC_AHBClockCmd(RCC_AHBPeriph_DCMI, ENABLE);
GPIO_InitTypeDef GPIO_Board_Init;
/*DCMI_CLK*/
GPIO_Board_Init.Pin = GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15;
GPIO_Board_Init.Speed = GPIO_HIGH_SPEED;
GPIO_Board_Init.Pull = GPIO_PULLUP;
GPIO_Board_Init.Mode = GPIO_MODE_AF;
GPIO_Board_Init.Otype = GPIO_MODE_OUTPUT_PP;
GPIO_Board_Init.SMIT = GPIO_INPUTSCHMIT_DISABLE;
GPIO_Init(GPIOB, &GPIO_Board_Init);
GPIO_PinAFConfig(GPIOB, GPIO_PIN_7, GPIO_AF1_DCMI);
GPIO_PinAFConfig(GPIOB, GPIO_PIN_8, GPIO_AF1_DCMI);
GPIO_PinAFConfig(GPIOB, GPIO_PIN_9, GPIO_AF1_DCMI);
GPIO_PinAFConfig(GPIOB, GPIO_PIN_10, GPIO_AF1_DCMI);
GPIO_PinAFConfig(GPIOB, GPIO_PIN_11, GPIO_AF1_DCMI);
GPIO_PinAFConfig(GPIOB, GPIO_PIN_12, GPIO_AF1_DCMI);
GPIO_PinAFConfig(GPIOB, GPIO_PIN_13, GPIO_AF1_DCMI);
GPIO_PinAFConfig(GPIOB, GPIO_PIN_14, GPIO_AF1_DCMI);
GPIO_PinAFConfig(GPIOB, GPIO_PIN_15, GPIO_AF1_DCMI);
/*DCMI_D6*/
GPIO_Board_Init.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2;
GPIO_Board_Init.Speed = GPIO_HIGH_SPEED;
GPIO_Board_Init.Pull = GPIO_PULLUP;
GPIO_Board_Init.Mode = GPIO_MODE_AF;
GPIO_Board_Init.Otype = GPIO_MODE_OUTPUT_PP;
GPIO_Board_Init.SMIT = GPIO_INPUTSCHMIT_DISABLE;
GPIO_Init(GPIOC, &GPIO_Board_Init);
GPIO_PinAFConfig(GPIOC, GPIO_PIN_0, GPIO_AF1_DCMI);
GPIO_PinAFConfig(GPIOC, GPIO_PIN_1, GPIO_AF1_DCMI);
GPIO_PinAFConfig(GPIOC, GPIO_PIN_2, GPIO_AF1_DCMI);
}
void DCMI_DMA_LLI_Init(uint32_t bufaddr, ImageSizeType dcmi_size)
{
uint16_t i, lli_len;
switch(dcmi_size)
{
case DCMI_640_480:
lli_len = 37; // (2048*37*4) + (1024*1*4)= 307200=640*480
for(i = 0; i < lli_len; i++)
{
dcmi_lli[i].source_addr = (uint32_t)&DCMI->DR;
dcmi_lli[i].dest_addr = (uint32_t)(&(((uint32_t *)bufaddr)[0x800 * (i + 1)]));
dcmi_lli[i].lli_addr = (uint32_t)&dcmi_lli[i + 1];
dcmi_lli[i].ctrl = 0x0A480800;
}
dcmi_lli[lli_len - 1].lli_addr = 0;
dcmi_lli[lli_len - 1].ctrl = 0x8A480400;
break;
case DCMI_320_240:
lli_len = 9; // (2048 * 9 * 4) + (768 * 4)=76800=320*240
for(i = 0; i < lli_len; i++)
{
dcmi_lli[i].source_addr = (uint32_t)&DCMI->DR;
dcmi_lli[i].dest_addr = (uint32_t)(&(((uint32_t *)bufaddr)[0x800 * (i + 1)]));
dcmi_lli[i].lli_addr = (uint32_t)&dcmi_lli[i + 1];
dcmi_lli[i].ctrl = 0x0A480800;
}
dcmi_lli[lli_len - 1].lli_addr = 0;
dcmi_lli[lli_len - 1].ctrl = 0x8A480300;
break;
case DCMI_160_240:
break;
default:
break;
}
}
extern uint8_t HaveToPlay(void);
uint8_t DCMI_CaptureOnePic(uint32_t bufaddr, ImageSizeType dcmi_size)
{
volatile uint8_t nCount;
nCount = 0;
DCMI_CaptureOnePicStart:
/*<2A><><EFBFBD><EFBFBD>LLI<4C><49><EFBFBD><EFBFBD> <20><>ǰһ֡ͼ<D6A1><CDBC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD>Ϊ320*240<34><30>DCMI һ<>ο<EFBFBD><CEBF>Բɼ<D4B2>һ<EFBFBD><D2BB>word<72><64><EFBFBD><EFBFBD><EFBFBD>ݣ<EFBFBD>2<EFBFBD><32><EFBFBD><EFBFBD><E3A3A9>DMA<4D><41><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ320*120= 38400<30><30>
DMAһ<EFBFBD>ΰ<EFBFBD><EFBFBD><EFBFBD>2048<EFBFBD><EFBFBD> 38400/2048 = 18.75 <EFBFBD><EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>19<EFBFBD><EFBFBD> ǰ18<EFBFBD><EFBFBD>ÿ<EFBFBD>ΰ<EFBFBD><EFBFBD><EFBFBD>2048<EFBFBD>Σ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD>ΰ<EFBFBD><EFBFBD><EFBFBD>1536<EFBFBD><EFBFBD>*/
DCMI_DMA_LLI_Init(bufaddr, dcmi_size);
/*<2A><><EFBFBD><EFBFBD>hdcmi<6D><69><EFBFBD><EFBFBD>*/
gHandleDCMI.Instance = DCMI;/*<2A><><EFBFBD><EFBFBD>DCMI<4D>Ĵ<EFBFBD><C4B4><EFBFBD><EFBFBD><EFBFBD>ַ*/
gHandleDCMI.DMA_Handle = &gHandleDMA;/*<2A><><EFBFBD><EFBFBD>hdcmi<6D><69>DMAָ<41><D6B8>ָ<EFBFBD><D6B8>hdma*/
gHandleDCMI.DMA_Handle->Instance = DMA_Channel7;/*<2A><><EFBFBD><EFBFBD>DMAͨ<41><CDA8>Ϊͨ<CEAA><CDA8>7*/
gHandleDCMI.DMA_Handle->Init.DestDataAlignment = DMA_DEST_ALIGN_WORD;/*<2A><><EFBFBD><EFBFBD>Ŀ<EFBFBD>İ<EFBFBD><C4B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>ΪWORD*/
gHandleDCMI.DMA_Handle->Init.SrcDataAlignment = DMA_SRC_ALIGN_WORD;/*<2A><><EFBFBD><EFBFBD>Դ<EFBFBD><D4B4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>ΪWORD*/
gHandleDCMI.DMA_Handle->Init.DestInc = DMA_DEST_INC_ENABLE;/*Ŀ<>İ<EFBFBD><C4B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>*/
gHandleDCMI.DMA_Handle->Init.SrcInc = DMA_SRC_INC_DISABLE;/*Դ<>İ<EFBFBD><C4B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>*/
gHandleDCMI.DMA_Handle->Init.RequestSelect = DMA_REQUEST_DCMI;/*DMA ģʽΪDCMI */
gHandleDCMI.DMA_Handle->Init.Direction = DMA_CTRL_PERIPH_TO_MEMORY;/*DMA <20><><EFBFBD>ƴ<EFBFBD><C6B4><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD>*/
gHandleDCMI.DMA_Handle->Init.IT_Enable = DMA_DEST_INC_DISABLE;
gHandleDCMI.DMA_Handle->Parent = &gHandleDCMI;
if(dcmi_size == DCMI_640_480)
{ DCMI_StructInit_Y640480(&gHandleDCMI.Init); }/*<2A><>ʼ<EFBFBD><CABC>DMCI<43><EFBFBD><E1B9B9>*/
else if(dcmi_size == DCMI_320_240)
{ DCMI_StructInit_RGB320240(&gHandleDCMI.Init); }
TMC_DCMI_Init(&gHandleDCMI);/*DCMI<4D><49>ʼ<EFBFBD><CABC>*/
TMC_DMA_DeInit(gHandleDCMI.DMA_Handle);/*DMA<4D><41>ʼ<EFBFBD><CABC>*/
TMC_DMA_Init(gHandleDCMI.DMA_Handle);/*DMA<4D><41>ʼ<EFBFBD><CABC>*/
TMC_DCMI_Start_DMA(&gHandleDCMI, DCMI_CAPTURE_SNAPSHOT, (u32)(&dcmi_lli[0]), bufaddr, 0x800); /*<2A>ɼ<EFBFBD><C9BC><EFBFBD>1<EFBFBD><31>2048word DMCI<43><49><EFBFBD><EFBFBD>*/
DCMI_ConfigImageCompress(DCMI_IMAGE_YCBCR, ENABLE);
DCMI_CaptureCmd(ENABLE);/*<2A><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>*/
TimerHSIClockCount(TIM3, START_TIMER);
gDCMICaptureFlag = 0;
nCount++;
while((gDCMICaptureFlag == 0)&&(nCount<4))/*<2A><><EFBFBD><EFBFBD> DCMI_Flag*/
{
if(HaveToPlay()||gKeyAction)
{
TMC_DCMI_DMAError(gHandleDCMI.DMA_Handle);
TimerHSIClockCount(TIM3, STOP_TIMER);
return 0;
}
if(TimerHSIClockCount(TIM3, GET_TIMER) >= CAMERA_TIMEOUE) //150ms
{
AppCameraInit();
TimerHSIClockCount(TIM3, STOP_TIMER);
goto DCMI_CaptureOnePicStart;
}
}
TimerHSIClockCount(TIM3, STOP_TIMER);
return 1;
}
/**
* @brief <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƽ<EFBFBD><EFBFBD><EFBFBD>;<EFBFBD>ֵ
* @param[in] ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>С.
* @retval <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ľ<EFBFBD>ֵ
*/
#define BLK_X_NUM 5
#define BLK_Y_NUM 3
#define BLK_W (320/BLK_X_NUM)
#define BLK_H (240/BLK_Y_NUM)
#define P(x,y,i,j) (y*BLK_H*320+x*BLK_W+i*320+j)
int DCMI_Differ(uint32_t dcmi_size)
{
uint32_t i,j,x,y, num,resu;
uint8_t *pData = (uint8_t *) DCMIBUFADDR;
for(x=0;x<BLK_X_NUM;x++)
for(y=0;y<BLK_Y_NUM;y++)
{
resu = 0;
for(i = 0; i < BLK_H; i++)
for(j = 0; j < BLK_W; j++)
{
num = P(x,y,i,j);
resu += (pData[num] - pData[num + dcmi_size])*(pData[num] - pData[num + dcmi_size]);
}
if(resu/BLK_W/BLK_H > gConfgBuf.sensitivity)
{
return TMC_OK;
}
}
return TMC_ERROR;
}
void AppCameraInit(void)
{
uint8_t ucTimerValue = 0;
//<2F><><EFBFBD><EFBFBD>DMAʱ<41><CAB1> ʹ<><CAB9>DMA<4D>ж<EFBFBD>
RCC_AHBClockCmd(RCC_AHBPeriph_DMA, ENABLE);
NVIC_SetPriorityGrouping(5);
NVIC_SetPriority(DMA_IRQn, 2);
NVIC_ClearPendingIRQ(DMA_IRQn);
NVIC_EnableIRQ(DMA_IRQn);
//<2F><><EFBFBD><EFBFBD>DCMIʱ<49><CAB1>
RCC_AHBClockCmd(RCC_AHBPeriph_DCMI, ENABLE);
//<2F><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
GPIO_MonitorClkOut(1, OSC_SOURCE_CLOCK_PLL_H, 3); //3 : 24MHz
gciCameraInfo.I2C_SCL.GPIOx = (void *)VBAT_GPIO;
gciCameraInfo.I2C_SCL.GPIO_PIN_x = 3;
gciCameraInfo.I2C_SDA.GPIOx = (void *)VBAT_GPIO;
gciCameraInfo.I2C_SDA.GPIO_PIN_x = 2;
gciCameraInfo.Camera_ClockSource = 1;
gciCameraInfo.Camera_PowerControl.GPIOx = (void *)GPIOD;
gciCameraInfo.Camera_PowerControl.GPIO_PIN_x = 10;
gciCameraInfo.Camera_Reset.GPIOx = (void *)GPIOD;
gciCameraInfo.Camera_Reset.GPIO_PIN_x = 4;
#if BCTCTEST
// <20><><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9>BF3007<30><37><EFBFBD><EFBFBD>ͷ
#endif
ucTimerValue = TMC_CAMERA_Init(&gciCameraInfo);
if(ucTimerValue != 0)
{
return;
}
}
void Sleep_Mode(void)
{
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ
GPIO_SetBits(CAMERA_POWER_PORT, CAMERA_POWER_PIN);
PWR_EnterSTOPMode(PWR_STOPEntry_WFE);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ
GPIO_ResetBits(CAMERA_POWER_PORT, CAMERA_POWER_PIN);
}