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

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

commit f1bc6aada3136e5503f593562e42727cfdf7c0b5
Author: SPRESENSE <41312067+sprese...@users.noreply.github.com>
AuthorDate: Tue Oct 17 10:09:40 2023 +0900

    drivers/video/isx019: Fix supported ISO sensitivity
    
    Support not continuous values but discrete values.
---
 drivers/video/isx019.c | 180 +++++++++++++++++++++++++++++++++++--------------
 1 file changed, 130 insertions(+), 50 deletions(-)

diff --git a/drivers/video/isx019.c b/drivers/video/isx019.c
index fd4796ef05..7ca13b53aa 100644
--- a/drivers/video/isx019.c
+++ b/drivers/video/isx019.c
@@ -221,7 +221,6 @@ struct isx019_dev_s
   uint8_t flip_still;
   isx019_rect_t clip_video;
   isx019_rect_t clip_still;
-  int32_t iso;
   double  gamma;
   int32_t jpg_quality;
   imgsensor_colorfx_t colorfx;
@@ -797,6 +796,96 @@ static const int32_t g_isx019_wbmode[] =
 
 #define NR_WBMODE (sizeof(g_isx019_wbmode) / sizeof(int32_t))
 
+static int32_t g_isx019_iso[] =
+{
+  1000,     /* ISO1 */
+  1200,     /* ISO1.2 */
+  1600,     /* ISO1.6 */
+  2000,     /* ISO2 */
+  2500,     /* ISO2.5 */
+  3000,     /* ISO3 */
+  4000,     /* ISO4 */
+  5000,     /* ISO5 */
+  6000,     /* ISO6 */
+  8000,     /* ISO8 */
+  10000,    /* ISO10 */
+  12000,    /* ISO12 */
+  16000,    /* ISO16 */
+  20000,    /* ISO20 */
+  25000,    /* ISO25 */
+  32000,    /* ISO32 */
+  40000,    /* ISO40 */
+  50000,    /* ISO50 */
+  64000,    /* ISO64 */
+  80000,    /* ISO80 */
+  100000,   /* ISO100 */
+  125000,   /* ISO125 */
+  160000,   /* ISO160 */
+  200000,   /* ISO200 */
+  250000,   /* ISO250 */
+  320000,   /* ISO320 */
+  400000,   /* ISO400 */
+  500000,   /* ISO500 */
+  640000,   /* ISO640 */
+  800000,   /* ISO800 */
+  1000000,  /* ISO1000 */
+  1250000,  /* ISO1250 */
+  1600000,  /* ISO1600 */
+  2000000,  /* ISO2000 */
+  2500000,  /* ISO2500 */
+  3200000,  /* ISO3200 */
+  4000000,  /* ISO4000 */
+  5000000,  /* ISO5000 */
+};
+
+#define NR_ISO (sizeof(g_isx019_iso) / sizeof(int32_t))
+
+/* Gain values corresponding to each element of g_isx019_iso table.
+ * This needs to have the same size as g_isx019_iso.
+ */
+
+static const uint8_t g_isx019_gain[] =
+{
+  1,   /* gain for ISO1 */
+  2,   /* gain for ISO1.2 */
+  3,   /* gain for ISO1.6 */
+  4,   /* gain for ISO2 */
+  5,   /* gain for ISO2.5 */
+  6,   /* gain for ISO3 */
+  7,   /* gain for ISO4 */
+  8,   /* gain for ISO5 */
+  9,   /* gain for ISO6 */
+  10,  /* gain for ISO8 */
+  11,  /* gain for ISO10 */
+  12,  /* gain for ISO12 */
+  13,  /* gain for ISO16 */
+  14,  /* gain for ISO20 */
+  15,  /* gain for ISO25 */
+  16,  /* gain for ISO32 */
+  17,  /* gain for ISO40 */
+  18,  /* gain for ISO50 */
+  19,  /* gain for ISO64 */
+  20,  /* gain for ISO80 */
+  21,  /* gain for ISO100 */
+  22,  /* gain for ISO125 */
+  23,  /* gain for ISO160 */
+  24,  /* gain for ISO200 */
+  25,  /* gain for ISO250 */
+  26,  /* gain for ISO320 */
+  27,  /* gain for ISO400 */
+  28,  /* gain for ISO500 */
+  29,  /* gain for ISO640 */
+  30,  /* gain for ISO800 */
+  31,  /* gain for ISO1000 */
+  32,  /* gain for ISO1250 */
+  33,  /* gain for ISO1600 */
+  34,  /* gain for ISO2000 */
+  35,  /* gain for ISO2500 */
+  36,  /* gain for ISO3200 */
+  37,  /* gain for ISO4000 */
+  38,  /* gain for ISO5000 */
+};
+
 /****************************************************************************
  * Private Functions
  ****************************************************************************/
@@ -1875,9 +1964,11 @@ static int isx019_get_supported_value(FAR struct 
imgsensor_s *sensor,
         break;
 
       case IMGSENSOR_ID_ISO_SENSITIVITY:
-        val->type = IMGSENSOR_CTRL_TYPE_INTEGER;
-        SET_RANGE(val->u.range, MIN_ISO, MAX_ISO,
-                                STEP_ISO, def->iso);
+        val->type = IMGSENSOR_CTRL_TYPE_INTEGER_MENU;
+        SET_DISCRETE(val->u.discrete,
+                     NR_ISO,
+                     g_isx019_iso,
+                     0);
         break;
 
       case IMGSENSOR_ID_ISO_SENSITIVITY_AUTO:
@@ -2578,18 +2669,21 @@ static int set_3aparameter(FAR isx019_dev_t *priv,
   return OK;
 }
 
-static uint16_t calc_gain(double iso)
+static uint16_t get_gain_from_iso(int32_t iso)
 {
-  double gain;
+  int i;
 
-  gain = 1 + 10 * log(iso) / M_LN10;
+  for (i = 0; i < NR_ISO; i++)
+    {
+      if (g_isx019_iso[i] == iso)
+        {
+          break;
+        }
+    }
 
-  /* In the above formula, the unit of gain is dB.
-   * Because the register has the 0.1dB unit,
-   * return 10 times dB value.
-   */
+  /* Return gain corresponding to specified ISO sensitivity. */
 
-  return (uint16_t)(gain * 10);
+  return (uint16_t)g_isx019_gain[i];
 }
 
 static int set_iso(FAR isx019_dev_t *priv,
@@ -2601,10 +2695,9 @@ static int set_iso(FAR isx019_dev_t *priv,
    * So, calculate gain from ISO sensitivity.
    */
 
-  gain = calc_gain(val.value32 / 1000);
+  gain = get_gain_from_iso(val.value32) * 10;
   isx019_i2c_write(priv, CAT_CATAE, GAIN_PRIMODE, &gain, 2);
 
-  priv->iso = val.value32;
   return OK;
 }
 
@@ -2617,7 +2710,6 @@ static int set_iso_auto(FAR isx019_dev_t *priv,
   if (val.value32 == IMGSENSOR_ISO_SENSITIVITY_AUTO)
     {
       gain = 0;
-      priv->iso = 0;
     }
   else /* IMGSENSOR_ISO_SENSITIVITY_MANUAL */
     {
@@ -2635,8 +2727,6 @@ static int set_iso_auto(FAR isx019_dev_t *priv,
           isx019_i2c_read(priv, CAT_AECOM, GAIN_LEVEL, &buf, 1);
           gain = buf * 3;
         }
-
-      priv->iso = val.value32;
     }
 
   return isx019_i2c_write(priv, CAT_CATAE, GAIN_PRIMODE, &gain, 2);
@@ -3293,56 +3383,46 @@ static int get_3astatus(FAR isx019_dev_t *priv,
   return OK;
 }
 
-static double calc_iso(double gain)
+static int32_t get_iso_from_gain(uint8_t gain)
 {
-  int k;
-  double z;
-  double r;
-
-  /* ISO sensitivity = 10^((gain - 1) / 10)
-   * So, replace z = (gain - 1) / 10 and
-   * calculate 10^z.
-   */
+  int i;
 
-  /*  Divide z into integer and other parts.
-   *  z =  log10(E) (k * ln2 + r)
-   *  (k : integer, r < 0.5 * ln2)
-   *
-   * Then, 10^z = (2^k) * e^r (r < 0.5 * ln2)
-   */
+  /* g_isx019_gain and g_isx019_iso has the common index. */
 
-  z = (gain - 1) / 10;
+  for (i = 0; i < NR_ISO; i++)
+    {
+      if (g_isx019_gain[i] == gain)
+        {
+          break;
+        }
+    }
 
-  k = z * M_LN10 / M_LN2;
-  r = z * M_LN10 - k * M_LN2;
+  if (i >= NR_ISO)
+    {
+      i = NR_ISO - 1;
+    }
 
-  return (1 << k) * exp(r);
+  return g_isx019_iso[i];
 }
 
 static int get_iso(FAR isx019_dev_t *priv,
                    FAR imgsensor_value_t *val)
 {
-  uint8_t buf = 0;
+  uint8_t gain = 0;
 
   if (val == NULL)
     {
       return -EINVAL;
     }
 
-  if (priv->iso == 0)
-    {
-      /* iso = 0 means auto adjustment mode.
-       * In such a case, get gain from auto adjustment value register,
-       * which has the unit 0.3dB, and convert the gain to ISO.
-       */
+  /* The current gain value register has the 0.3dB unit.
+   * So, round the gain to integer, and convert to ISO.
+   */
 
-      isx019_i2c_read(priv, CAT_AECOM, GAIN_LEVEL, &buf, 1);
-      val->value32 = calc_iso((double)buf * 0.3) * USEC_PER_MSEC;
-    }
-  else
-    {
-      val->value32 = priv->iso;
-    }
+  isx019_i2c_read(priv, CAT_AECOM, GAIN_LEVEL, &gain, 1);
+  gain = ((gain * 3) + 5) / 10;
+
+  val->value32 = get_iso_from_gain(gain);
 
   return OK;
 }

Reply via email to