luochengPC 2 роки тому
батько
коміт
fd41ddea6b
2 змінених файлів з 180 додано та 53 видалено
  1. 177 50
      std/camera/sensors/ov2640.c
  2. 3 3
      std/src/user_twim.c

+ 177 - 50
std/camera/sensors/ov2640.c

@@ -6,14 +6,21 @@
 #include "app_timer.h"
 
 static custome_event ov2640_event;
-APP_TIMER_DEF(ov2640_timer_id);
+static void Set_Ov2640_Queue(OV2640_QUEUE_TYPE type);
+static ov2640_work_e ov2640_work = OV2640_WORK_RST;
 
+APP_TIMER_DEF(ov2640_timer_id);
 static uint32_t ov2640_timer_tick = 0;
 static bool ov2640_timer_end = true;
 static bool ov2640_timer_stat = false;
 
-void Set_Ov2640_Queue(OV2640_QUEUE_TYPE type);
+//TWI传输完成标志
+static volatile bool m_xfer_done = false;
+//TWI传输超时标志
+static volatile bool m_xfer_timeout = false;
 
+static uint8_t OV2640_ReadReg(uint16_t Addr);
+static ret_code_t OV2640_WriteReg(uint16_t Addr, uint8_t Data);
 /** @addtogroup 
   * @{
   */
@@ -557,25 +564,30 @@ void OV2640_CaptureGpioInit(nrf_drv_gpiote_in_config_t *config,nrfx_gpiote_evt_h
 
 static void ov2640_i2s_done(void)
 {
-	
+	m_xfer_done = true;
 }
 
 static void ov2640_i2s_timeout(void)
 {
-	
+	m_xfer_timeout = true;
 }
 
-void OV2640_i2s_Init(void)
+void OV2640_i2s_init(void)
 {
  	twim0_init(ov2640_i2s_done, ov2640_i2s_timeout);
 }
 
+void OV2640_i2s_uninit(void)
+{
+ 	twim0_uinit();
+}
+
 /**
   * @brief  Resets the OV2640 camera.
   * @param  None
   * @retval None
   */
-void OV2640_Reset(void)
+static void OV2640_Reset(void)
 {
   OV2640_WriteReg(OV2640_DSP_RA_DLMT, 0x01);
   OV2640_WriteReg(OV2640_SENSOR_COM7, 0x80);
@@ -586,7 +598,7 @@ void OV2640_Reset(void)
   * @param  OV2640ID: Pointer to the OV2640 Manufacturer identifier
   * @retval None
   */
-void OV2640_ReadID(OV2640_IDTypeDef *OV2640ID)
+static void OV2640_ReadID(OV2640_IDTypeDef *OV2640ID)
 {
   OV2640_WriteReg(OV2640_DSP_RA_DLMT, 0x01);
   OV2640ID->Manufacturer_ID1 = OV2640_ReadReg(OV2640_SENSOR_MIDH);
@@ -595,51 +607,51 @@ void OV2640_ReadID(OV2640_IDTypeDef *OV2640ID)
   OV2640ID->PIDL = OV2640_ReadReg(OV2640_SENSOR_PIDL);
 }
 
-/**
-  * @brief  Configures the OV2640 camera in JPEG mode.
-  * @param  JPEGImageSize: JPEG image size
-  * @retval None
-  */
-void OV2640_JPEGConfig(void)
+static void ov2640_cmd_jpeg_init(void)
 {
-  uint32_t i;
-
-  OV2640_Reset();
-  Delay_nMS(200);
-
-  /* Initialize OV2640 */
-  for(i=0; i<(sizeof(OV2640_JPEG_INIT)/2); i++)
+	/* Initialize OV2640 */
+  for(int i=0; i<(sizeof(OV2640_JPEG_INIT)/2); i++)
   {
     OV2640_WriteReg(OV2640_JPEG_INIT[i][0], OV2640_JPEG_INIT[i][1]);
-		Delay_nMS(1);
+		nrf_delay_us(100);
   }
+}
 
-  /* Set to output YUV422 */
-  for(i=0; i<(sizeof(OV2640_YUV422)/2); i++)
+static void ov2640_cmd_yuv422(void)
+{
+	/* Set to output YUV422 */
+  for(int i=0; i<(sizeof(OV2640_YUV422)/2); i++)
   {
     OV2640_WriteReg(OV2640_YUV422[i][0], OV2640_YUV422[i][1]);
-		Delay_nMS(1);
+		nrf_delay_us(100);
   }
+}
 
-  OV2640_WriteReg(0xff, 0x01);
+static void ov2640_cmd_jpeg(void)
+{
+	OV2640_WriteReg(0xff, 0x01);
   OV2640_WriteReg(0x15, 0x00);
-
-  /* Set to output JPEG */
-  for(i=0; i<(sizeof(OV2640_JPEG)/2); i++)
+	
+	/* Set to output JPEG */
+  for(int i=0; i<(sizeof(OV2640_JPEG)/2); i++)
   {
     OV2640_WriteReg(OV2640_JPEG[i][0], OV2640_JPEG[i][1]);
-	Delay_nMS(1);
+		nrf_delay_us(100);
   }
+}
 
-  Delay_nMS(100);
-	
-	for(i=0; i<(sizeof(OV2640_800x600_JPEG)/2); i++)
+/**
+  * @brief  Configures the OV2640 camera in JPEG mode.
+  * @param  JPEGImageSize: JPEG image size
+  * @retval None
+  */
+void OV2640_JPEGConfig(void)
+{
+  for(int i=0; i<(sizeof(OV2640_800x600_JPEG)/2); i++)
 	{
 		OV2640_WriteReg(OV2640_800x600_JPEG[i][0], OV2640_800x600_JPEG[i][1]);
-		Delay_nMS(1);
+		nrf_delay_us(100);
 	}
-  
-  
 }
 
 /**
@@ -715,7 +727,8 @@ void SCCB_WriteRegs(const uint8_t* pbuf)
 		}
 		else
 		{
-			OV2640_WriteReg(*pbuf++, *pbuf++);
+			OV2640_WriteReg(*pbuf, *(pbuf+1));
+			pbuf += 2;
 		}
 	}
 }
@@ -815,17 +828,27 @@ void OV2640_ContrastConfig(uint8_t value1, uint8_t value2)
   * @retval 0x00 if write operation is OK.
   *       0xFF if timeout condition occured (device not connected or bus error).
   */
-uint8_t OV2640_WriteReg(uint16_t Addr, uint8_t Data)
+static ret_code_t OV2640_WriteReg(uint16_t Addr, uint8_t Data)
 {
 	uint8_t sdata[3] = {0};
 	
 	memcpy(sdata, &Addr, 2);
 	sdata[2] = Data;
 	
-  nrf_drv_twim0_tx(OV2640_DEVICE_WRITE_ADDRESS, sdata, 3, true);
-  
+	m_xfer_done = false;
+  nrf_drv_twim0_tx(OV2640_DEVICE_WRITE_ADDRESS, sdata, 3, false);
+  while((m_xfer_done == false) && (m_xfer_timeout == false))
+	{
+		
+	}
+	
+  if(m_xfer_done == false)
+  {
+		return NRF_ERROR_TIMEOUT;
+	}
+	
   /* If operation is OK, return 0 */
-  return 0;
+  return NRF_SUCCESS;
 }
 
 /**
@@ -834,12 +857,36 @@ uint8_t OV2640_WriteReg(uint16_t Addr, uint8_t Data)
   * @retval data read from the specific register or 0xFF if timeout condition
   *         occured. 
   */
-uint8_t OV2640_ReadReg(uint16_t Addr)
+static uint8_t OV2640_ReadReg(uint16_t Addr)
 {
 	uint8_t recv_data = 0;
-	nrf_drv_twim0_rx(OV2640_DEVICE_WRITE_ADDRESS, recv_data, 1);
+	uint8_t sdata[2] = {0};
+	
+	memcpy(sdata, &Addr, 2);
+	m_xfer_done = false;
+	nrf_drv_twim0_tx(OV2640_DEVICE_WRITE_ADDRESS, sdata, 2, true);
+	while((m_xfer_done == false) && (m_xfer_timeout == false))
+	{
+		
+	}
+	
+  if(m_xfer_done == false)
+  {
+		return NRF_ERROR_TIMEOUT;
+	}
+	
+	nrf_drv_twim0_rx(OV2640_DEVICE_WRITE_ADDRESS, &recv_data, 1);
+	while((m_xfer_done == false) && (m_xfer_timeout == false))
+	{
+		
+	}
+	
+  if(m_xfer_done == false)
+  {
+		return NRF_ERROR_TIMEOUT;
+	}
   /* return the read data */
-  return Data;
+  return recv_data;
 }
 
 static uint8_t get_ov2640_data(void)
@@ -881,16 +928,96 @@ static uint8_t get_ov2640_data(void)
 	return data;
 }
 
-void ov2640_init(void)
+//void ov2640_init(void)
+//{
+
+//	OV2640_ReadID(&OV2640_Camera_ID);	//读取OV2640ID,测试硬件,依次为:0x7F,0xA2,0x26,0x42
+//	OV2640_JPEGConfig(JPEG_320x240);	//配置OV2640输出320*240像素的JPG图片
+//	
+//	OV2640_BrightnessConfig(0x20);
+//	OV2640_AutoExposure(2);
+//}
+
+static void ov2640_pro(void)
+{
+	switch(ov2640_work)
+	{
+		case OV2640_WORK_I2C_INIT:{
+			OV2640_i2s_init();
+			ov2640_work = OV2640_WORK_RST;
+			ov2640_timers_work(1);
+		}break;
+		case OV2640_WORK_RST:{
+			OV2640_Reset();
+			ov2640_work = OV2640_WORK_JPEG_INIT;
+			ov2640_timers_work(100);
+		}break;
+		case OV2640_WORK_JPEG_INIT:{
+			ov2640_cmd_jpeg_init();
+			ov2640_work = OV2640_WORK_YUV422;
+			ov2640_timers_work(1);
+		}break;
+		case OV2640_WORK_YUV422:{
+			ov2640_cmd_yuv422();
+			ov2640_work = OV2640_WORK_JPEG;
+			ov2640_timers_work(1);
+		}break;
+		case OV2640_WORK_JPEG:{
+			ov2640_cmd_jpeg();
+			ov2640_work = OV2640_WORK_JPEGCONFIG;
+			ov2640_timers_work(1);
+		}break;
+		case OV2640_WORK_JPEGCONFIG:{
+			OV2640_JPEGConfig();
+			ov2640_work = OV2640_WORK_BNCONFIG;
+			ov2640_timers_work(1);
+		}break;
+		case OV2640_WORK_BNCONFIG:{
+			OV2640_BrightnessConfig(0x20);
+			ov2640_work = OV2640_WORK_AUTOEXP;
+			ov2640_timers_work(1);
+		}break;
+		case OV2640_WORK_AUTOEXP:{
+			OV2640_AutoExposure(2);
+			ov2640_work = OV2640_WORK_I2C_UNINIT;
+			ov2640_timers_work(1);
+		}break;
+		case OV2640_WORK_VSYNC:{
+			
+		}break;
+		case OV2640_WORK_PCLK:{
+			
+		}break;
+		case OV2640_WORK_HREF:{
+			
+		}break;
+		case OV2640_WORK_I2C_UNINIT:{
+			OV2640_i2s_uninit();
+			ov2640_work = OV2640_WORK_I2C_INIT;
+		}break;
+	}
+}
+
+static void ov2640_queue(void *p_event_data, uint16_t event_size)    
 {
-	OV2640_HW_Init();					//IIC初始化
-	OV2640_ReadID(&OV2640_Camera_ID);	//读取OV2640ID,测试硬件,依次为:0x7F,0xA2,0x26,0x42
-	OV2640_JPEGConfig(JPEG_320x240);	//配置OV2640输出320*240像素的JPG图片
-	//设置自动曝光和白平衡
-	OV2640_BrightnessConfig(0x20);
-	OV2640_AutoExposure(2);
+	custome_event *evt = (custome_event*)p_event_data;
+	if((ov2640_event.flag & (1 << OV2640_QUEUE_INT)) != 0)
+	{
+		ov2640_pro();
+		ov2640_event.flag &= (~(1 << OV2640_QUEUE_INT));
+	}
+	if((ov2640_event.flag & (1 << OV2640_QUEUE_TIME)) != 0)
+	{
+		ov2640_pro();
+		ov2640_event.flag &= (~(1 << OV2640_QUEUE_TIME));
+	}
 }
 
+static void Set_Ov2640_Queue(OV2640_QUEUE_TYPE type)
+{
+	ov2640_event.flag |= (1<<type);
+	ret_code_t err_code = app_sched_event_put(&ov2640_event, sizeof(ov2640_event), ov2640_queue);
+}
 
 
 /**

+ 3 - 3
std/src/user_twim.c

@@ -116,13 +116,13 @@ static void twim1_handler(nrf_drv_twi_evt_t const * p_event, void * p_context)
 	{
 		//传输完成事件
 		case NRF_DRV_TWI_EVT_DONE:
-			user_twim1_s.twim_xfer_done(true);//置位传输完成标志
+			user_twim1_s.twim_xfer_done();//置位传输完成标志
 			break;
 		case NRF_DRV_TWI_EVT_ADDRESS_NACK:
-			user_twim1_s.twim_xfer_timeout(true);//传输超时
+			user_twim1_s.twim_xfer_timeout();//传输超时
 			break;
 		case NRF_DRV_TWI_EVT_DATA_NACK:
-			user_twim1_s.twim_xfer_timeout(true);
+			user_twim1_s.twim_xfer_timeout();
 			break;
 		default:
 			break;