You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by je...@apache.org on 2024/03/11 14:44:53 UTC
(nuttx) 07/15: drivers/video/isx019: Fix bug that read value is not correct
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 fd5c2d49225cb51a6831c2f67925a4d4bed42e84
Author: SPRESENSE <41...@users.noreply.github.com>
AuthorDate: Thu Dec 21 15:26:35 2023 +0900
drivers/video/isx019: Fix bug that read value is not correct
About parameter whose register size is less than 4 bytes,
when transfer read value to API parameter, cast appropriately
to avoid the following problems.
- Read value includes garbage value
- Negative value becomes huge positive value
---
drivers/video/isx019.c | 61 +++++++++++++++++++++++++++++++++++++++-----------
1 file changed, 48 insertions(+), 13 deletions(-)
diff --git a/drivers/video/isx019.c b/drivers/video/isx019.c
index a763328c94..d7aa292414 100644
--- a/drivers/video/isx019.c
+++ b/drivers/video/isx019.c
@@ -99,14 +99,27 @@
/* For set_value() and get_value() I/F */
-#define SET_REGINFO(a, c, o, s) do \
+#define SET_REGINFO(a, c, o, t, s) do \
{ \
(a)->category = (c); \
(a)->offset = (o); \
+ (a)->type = (t); \
(a)->size = (s); \
} \
while (0);
+/* Register type, which represents the number of bits and
+ * whether it is signed or unsigned.
+ */
+
+#define ISX019_REGTYPE_INT8 (0)
+#define ISX019_REGTYPE_UINT8 (1)
+#define ISX019_REGTYPE_INT16 (2)
+
+#define SET_REGINFO_INT8(a, c, o) SET_REGINFO(a, c, o, ISX019_REGTYPE_INT8, 1)
+#define SET_REGINFO_UINT8(a, c, o) SET_REGINFO(a, c, o, ISX019_REGTYPE_UINT8, 1)
+#define SET_REGINFO_INT16(a, c, o) SET_REGINFO(a, c, o, ISX019_REGTYPE_INT16, 2)
+
#define VALIDATE_RANGE(v, min, max, step) (((v) >= (min)) && \
((v) <= (max)) && \
(((v) - (min)) % (step) == 0))
@@ -239,6 +252,7 @@ struct isx019_reginfo_s
{
uint16_t category;
uint16_t offset;
+ uint8_t type;
uint8_t size;
};
@@ -2040,12 +2054,12 @@ static int32_t not_convert(int32_t val)
static int32_t convert_brightness_is2reg(int32_t val)
{
- return (val << 2);
+ return (val * 4);
}
static int32_t convert_brightness_reg2is(int32_t val)
{
- return (val >> 2);
+ return (val / 4);
}
static int32_t convert_hue_is2reg(int32_t val)
@@ -2119,38 +2133,38 @@ static convert_t get_reginfo(uint32_t id, bool is_set,
switch (id)
{
case IMGSENSOR_ID_BRIGHTNESS:
- SET_REGINFO(reg, CAT_PICTTUNE, UIBRIGHTNESS, 2);
+ SET_REGINFO_INT16(reg, CAT_PICTTUNE, UIBRIGHTNESS);
cvrt = is_set ? convert_brightness_is2reg
: convert_brightness_reg2is;
break;
case IMGSENSOR_ID_CONTRAST:
- SET_REGINFO(reg, CAT_PICTTUNE, UICONTRAST, 1);
+ SET_REGINFO_UINT8(reg, CAT_PICTTUNE, UICONTRAST);
cvrt = not_convert;
break;
case IMGSENSOR_ID_SATURATION:
- SET_REGINFO(reg, CAT_PICTTUNE, UISATURATION, 1);
+ SET_REGINFO_UINT8(reg, CAT_PICTTUNE, UISATURATION);
cvrt = not_convert;
break;
case IMGSENSOR_ID_HUE:
- SET_REGINFO(reg, CAT_PICTTUNE, UIHUE, 1);
+ SET_REGINFO_INT8(reg, CAT_PICTTUNE, UIHUE);
cvrt = is_set ? convert_hue_is2reg : convert_hue_reg2is;
break;
case IMGSENSOR_ID_EXPOSURE:
- SET_REGINFO(reg, CAT_AEDGRM, EVSEL, 1);
+ SET_REGINFO_INT8(reg, CAT_AEDGRM, EVSEL);
cvrt = not_convert;
break;
case IMGSENSOR_ID_SHARPNESS:
- SET_REGINFO(reg, CAT_PICTTUNE, UISHARPNESS, 1);
+ SET_REGINFO_UINT8(reg, CAT_PICTTUNE, UISHARPNESS);
cvrt = not_convert;
break;
case IMGSENSOR_ID_WIDE_DYNAMIC_RANGE:
- SET_REGINFO(reg, CAT_AEWD, AEWDMODE, 1);
+ SET_REGINFO_UINT8(reg, CAT_AEWD, AEWDMODE);
cvrt = is_set ? convert_hdr_is2reg : convert_hdr_reg2is;
break;
@@ -3568,16 +3582,37 @@ static int isx019_get_value(FAR struct imgsensor_s *sensor,
isx019_reginfo_t reg;
convert_t cvrt;
getvalue_t get;
- int32_t val32;
+ union
+ {
+ int32_t i32;
+ int16_t i16;
+ int8_t i8;
+ } regval;
DEBUGASSERT(val);
cvrt = get_reginfo(id, false, ®);
if (cvrt)
{
+ memset(®val, 0, sizeof(regval));
ret = isx019_i2c_read(priv,
- reg.category, reg.offset, &val32, reg.size);
- val->value32 = cvrt(val32);
+ reg.category, reg.offset, ®val.i32, reg.size);
+
+ switch (reg.type)
+ {
+ case ISX019_REGTYPE_INT8:
+ regval.i32 = (int32_t)regval.i8;
+ break;
+
+ case ISX019_REGTYPE_INT16:
+ regval.i32 = (int32_t)regval.i16;
+ break;
+
+ default:
+ break;
+ }
+
+ val->value32 = cvrt(regval.i32);
}
else
{