This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git

commit 5e4e8f680978f9f01b84783bda3a08096e70971a
Author: SPRESENSE <41312067+sprese...@users.noreply.github.com>
AuthorDate: Mon Oct 24 22:40:27 2022 +0900

    drivers/video/isx019: Fix white balance control and capability
---
 drivers/video/isx019.c | 156 +++++++++++++++++++++++++++++++++++--------------
 1 file changed, 112 insertions(+), 44 deletions(-)

diff --git a/drivers/video/isx019.c b/drivers/video/isx019.c
index c6463d2b07..f128ae5ce3 100644
--- a/drivers/video/isx019.c
+++ b/drivers/video/isx019.c
@@ -282,6 +282,7 @@ static int isx019_get_value(uint32_t id, uint32_t size,
 static int isx019_set_value(uint32_t id, uint32_t size,
                             imgsensor_value_t value);
 static int initialize_jpg_quality(void);
+static void initialize_wbmode(void);
 static int send_read_cmd(FAR struct i2c_config_s *config,
                          uint8_t cat,
                          uint16_t addr,
@@ -770,7 +771,7 @@ int32_t g_isx019_wbmode[] =
  * Private Functions
  ****************************************************************************/
 
-int fpga_i2c_write(uint8_t addr, FAR uint8_t *data, uint8_t size)
+static int fpga_i2c_write(uint8_t addr, FAR uint8_t *data, uint8_t size)
 {
   struct i2c_config_s config;
   static uint8_t buf[FPGA_I2C_REGSIZE_MAX + FPGA_I2C_REGADDR_LEN];
@@ -1211,6 +1212,7 @@ static int isx019_init(void)
   power_on();
   set_drive_mode();
   fpga_init();
+  initialize_wbmode();
   initialize_jpg_quality();
   store_default_value();
   clk = board_isx019_get_master_clock();
@@ -1423,7 +1425,7 @@ static int activate_clip(imgsensor_stream_type_t type,
 
         break;
 
-      default: /* 640 */
+      case 640:
         if (clip->width == 640)
           {
             /* In this case, clip->height == 360 */
@@ -1451,6 +1453,13 @@ static int activate_clip(imgsensor_stream_type_t type,
           }
 
         break;
+
+      default: /* Otherwise, clear clip setting. */
+        size = FPGA_CLIP_NON;
+        top  = 0;
+        left = 0;
+
+        break;
     }
 
   fpga_i2c_write(FPGA_CLIP_SIZE, &size, 1);
@@ -1512,30 +1521,27 @@ static int isx019_start_capture(imgsensor_stream_type_t 
type,
     }
 
   switch (fmt[IMGSENSOR_FMT_MAIN].width)
-   {
-     case 1280:
-       regval |= FPGA_SCALE_1280_960;
-       activate_clip(type,
-                     fmt[IMGSENSOR_FMT_MAIN].width,
-                     fmt[IMGSENSOR_FMT_MAIN].height);
-       break;
-
-     case 640:
-       regval |= FPGA_SCALE_640_480;
-       activate_clip(type,
-                     fmt[IMGSENSOR_FMT_MAIN].width,
-                     fmt[IMGSENSOR_FMT_MAIN].height);
-       break;
-
-     case 320:
-       regval |= FPGA_SCALE_320_240;
-       break;
-
-     default: /* 160 */
-
-       regval |= FPGA_SCALE_160_120;
-       break;
-   }
+    {
+      case 1280:
+        regval |= FPGA_SCALE_1280_960;
+        break;
+
+      case 640:
+        regval |= FPGA_SCALE_640_480;
+        break;
+
+      case 320:
+        regval |= FPGA_SCALE_320_240;
+        break;
+
+      default: /* 160 */
+        regval |= FPGA_SCALE_160_120;
+        break;
+    }
+
+  activate_clip(type,
+                fmt[IMGSENSOR_FMT_MAIN].width,
+                fmt[IMGSENSOR_FMT_MAIN].height);
 
   fpga_i2c_write(FPGA_FORMAT_AND_SCALE, &regval, 1);
 
@@ -1894,16 +1900,6 @@ static int32_t convert_hue_reg2is(int32_t val)
   return (val * 128) / 90;
 }
 
-static int32_t convert_awb_is2reg(int32_t val)
-{
-  return (val == 1) ? 0 : 2;
-}
-
-static int32_t convert_awb_reg2is(int32_t val)
-{
-  return (val == 0) ? 1 : 0;
-}
-
 static int32_t convert_hdr_is2reg(int32_t val)
 {
   int32_t ret = AEWDMODE_AUTO;
@@ -1985,11 +1981,6 @@ static convert_t get_reginfo(uint32_t id, bool is_set,
         cvrt = is_set ? convert_hue_is2reg : convert_hue_reg2is;
         break;
 
-      case IMGSENSOR_ID_AUTO_WHITE_BALANCE:
-        SET_REGINFO(reg, CAT_CATAWB, AWBMODE, 1);
-        cvrt = is_set ? convert_awb_is2reg : convert_awb_reg2is;
-        break;
-
       case IMGSENSOR_ID_EXPOSURE:
         SET_REGINFO(reg, CAT_AEDGRM, EVSEL, 1);
         cvrt = not_convert;
@@ -2147,7 +2138,18 @@ static int set_exptime(imgsensor_value_t val)
   return isx019_i2c_write(CAT_CATAE, SHT_PRIMODE, (FAR uint8_t *)&regval, 4);
 }
 
-static int set_wbmode(imgsensor_value_t val)
+static int set_awb_hold(void)
+{
+  uint8_t mode = AWBMODE_HOLD;
+  return isx019_i2c_write(CAT_CATAWB, AWBMODE, &mode, 1);
+}
+
+static void initialize_wbmode(void)
+{
+  g_isx019_private.wb_mode = IMGSENSOR_WHITE_BALANCE_AUTO;
+}
+
+static int update_wbmode_reg(int32_t val)
 {
   /*  AWBMODE     mode0 : auto, mode4 : user defined white balance
    *  AWBUSER_NO  definition number for AWBMODE = mode4
@@ -2175,7 +2177,7 @@ static int set_wbmode(imgsensor_value_t val)
       toggle = true;
     }
 
-  switch (val.value32)
+  switch (val)
     {
       case IMGSENSOR_WHITE_BALANCE_AUTO:
         mode = AWBMODE_AUTO;
@@ -2217,7 +2219,53 @@ static int set_wbmode(imgsensor_value_t val)
   isx019_i2c_write(CAT_CATAWB, AWBUSER_NO, (FAR uint8_t *)&toggle, 1);
   isx019_i2c_write(CAT_CATAWB, AWBMODE, &mode, 1);
 
+  return OK;
+}
+
+static bool is_awb_enable(void)
+{
+  uint8_t mode = AWBMODE_AUTO;
+
+  isx019_i2c_read(CAT_CATAWB, AWBMODE, &mode, 1);
+
+  return mode != AWBMODE_HOLD;
+}
+
+static int set_wbmode(imgsensor_value_t val)
+{
+  /* Update register only if IMGSENSOR_ID_AUTO_WHITE_BALANCE = 1. */
+
+  if (is_awb_enable())
+    {
+      update_wbmode_reg(val.value32);
+    }
+
   g_isx019_private.wb_mode = val.value32;
+  return OK;
+}
+
+static int set_awb(imgsensor_value_t val)
+{
+  /* true  -> false : Update regster to HOLD
+   * false -> true  : Update register
+   *                  with IMGSENSOR_ID_AUTO_N_PRESET_WB setting
+   * otherwise      : Nothing to do
+   */
+
+  if (is_awb_enable())
+    {
+      if (val.value32 == 0)
+        {
+          set_awb_hold();
+        }
+    }
+  else
+    {
+      if (val.value32 == 1)
+        {
+          update_wbmode_reg(g_isx019_private.wb_mode);
+        }
+    }
 
   return OK;
 }
@@ -2644,6 +2692,10 @@ static setvalue_t set_value_func(uint32_t id)
         func = set_exptime;
         break;
 
+      case IMGSENSOR_ID_AUTO_WHITE_BALANCE:
+        func = set_awb;
+        break;
+
       case IMGSENSOR_ID_AUTO_N_PRESET_WB:
         func = set_wbmode;
         break;
@@ -2687,7 +2739,7 @@ static setvalue_t set_value_func(uint32_t id)
   return func;
 }
 
-static int32_t get_flip(uint8_t *flip, uint8_t direction)
+static int32_t get_flip(FAR uint8_t *flip, uint8_t direction)
 {
   DEBUGASSERT(flip);
 
@@ -2782,6 +2834,18 @@ static int get_exptime(FAR imgsensor_value_t *val)
   return OK;
 }
 
+static int get_awb(FAR imgsensor_value_t *val)
+{
+  if (val == NULL)
+    {
+      return -EINVAL;
+    }
+
+  val->value32 = is_awb_enable();
+
+  return OK;
+}
+
 static int get_wbmode(FAR imgsensor_value_t *val)
 {
   if (val == NULL)
@@ -3032,6 +3096,10 @@ static getvalue_t get_value_func(uint32_t id)
         func = get_exptime;
         break;
 
+      case IMGSENSOR_ID_AUTO_WHITE_BALANCE:
+        func = get_awb;
+        break;
+
       case IMGSENSOR_ID_AUTO_N_PRESET_WB:
         func = get_wbmode;
         break;

Reply via email to