2020-09-12 12:38 AM
Hello,
I'm try using ISM330DLC connect to Linux OS on board IMX8MP via I2C
Linux supported driver for this device (iio/imu/st_lsm6dsx); I added to dts file as below:
&i2c5 {
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c5>;
pinctrl-assert-gpios = <&pca6416 2 GPIO_ACTIVE_HIGH>; /* i2c5 pin conflict with can1: default gpio low select can1, gpio high select i2c5 */
status = "okay";
ism330dlc@6b {
compatible = "st,ism330dlc";
reg = <0x6b>;
st,drdy-int-pin = <1>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ioexp_int>;
interrupt-parent = <&gpio1>;
interrupts = <12 IRQ_TYPE_EDGE_RISING>;
};
};
But I didn't see any interrupt signal to Linux
# cat /proc/interrupts | grep 12
6: 12073 10115 14187 8714 GPCv2 i.MX8MQ 47 Level timer@306a0000
38: 127 0 0 0 GPCv2 i.MX8MQ 76 Level 30ad0000.i2c
46: 6787 0 0 0 GPCv2 i.MX8MQ 120 Level 30be0000.ethernet
50: 0 0 0 0 GPCv2 i.MX8MQ 122 Level 30c90000.easrc
56: 0 0 0 0 GPCv2 i.MX8MQ 128 Level 30cc0000.xcvr
57: 0 0 0 0 GPCv2 i.MX8MQ 129 Level 30cc0000.xcvr
95: 0 0 0 0 gpio-mxc 12 Edge lsm6dsx
127: 0 0 0 0 gpio-mxc 12 Edge 30b50000.mmc cd
could you give some recommend to resolve this issue ?
Thanks in advance !
tam do
Solved! Go to Solution.
2020-09-21 09:02 AM
Resolved:
In my case, I have to do more steps with this driver to resolve issue:
diff --git a/drivers/iio/imu/st_ism330dlc/st_ism330dlc_core.c b/drivers/iio/imu/st_ism330dlc/st_ism330dlc_core.c
index 998d234..d326d74 100644
--- a/drivers/iio/imu/st_ism330dlc/st_ism330dlc_core.c
+++ b/drivers/iio/imu/st_ism330dlc/st_ism330dlc_core.c
@@ -117,6 +117,14 @@
#define ST_ISM330DLC_SELFTEST_FAIL_MS "fail"
#define ST_ISM330DLC_SELFTEST_PASS_MS "pass"
+
+#define ST_ISM330DLC_DRDY_PULSED_ADDR 0x0b
+#define ST_ISM330DLC_DRDY_PULSED_MASK 0x80
+
+#define ST_ISM330DLC_DRDY_ON_INT1_ADDR 0x1a
+#define ST_ISM330DLC_DRDY_ON_INT1_MASK 0x80
+
+
/* CUSTOM VALUES FOR ACCEL SENSOR */
#define ST_ISM330DLC_ACCEL_ODR_ADDR 0x10
#define ST_ISM330DLC_ACCEL_ODR_MASK 0xf0
@@ -1723,10 +1731,10 @@ static int st_ism330dlc_init_sensor(struct ism330dlc_data *cdata)
msleep(200);
/* Latch interrupts */
- err = st_ism330dlc_write_data_with_mask(cdata, ST_ISM330DLC_LIR_ADDR,
- ST_ISM330DLC_LIR_MASK, ST_ISM330DLC_EN_BIT, true);
- if (err < 0)
- return err;
+// err = st_ism330dlc_write_data_with_mask(cdata, ST_ISM330DLC_LIR_ADDR,
+// ST_ISM330DLC_LIR_MASK, ST_ISM330DLC_EN_BIT, true);
+// if (err < 0)
+// return err;
/* Enable BDU for sensors data */
err = st_ism330dlc_write_data_with_mask(cdata, ST_ISM330DLC_BDU_ADDR,
@@ -1741,6 +1749,15 @@ static int st_ism330dlc_init_sensor(struct ism330dlc_data *cdata)
if (err < 0)
return err;
+ /* Enable pulsed data-ready mode */
+ err = st_ism330dlc_write_data_with_mask(cdata,
+ ST_ISM330DLC_DRDY_PULSED_ADDR,
+ ST_ISM330DLC_DRDY_PULSED_MASK,
+ ST_ISM330DLC_EN_BIT, true);
+ if (err < 0)
+ return err;
+
+
/* Redirect INT2 on INT1, all interrupt will be available on INT1 */
err = st_ism330dlc_write_data_with_mask(cdata,
ST_ISM330DLC_INT2_ON_INT1_ADDR,
@@ -1749,6 +1766,14 @@ static int st_ism330dlc_init_sensor(struct ism330dlc_data *cdata)
if (err < 0)
return err;
+ /* Enable master DRDY on INT1 */
+ err = st_ism330dlc_write_data_with_mask(cdata,
+ ST_ISM330DLC_DRDY_ON_INT1_ADDR,
+ ST_ISM330DLC_DRDY_ON_INT1_MASK,
+ ST_ISM330DLC_EN_BIT, true);
+ if (err < 0)
+ return err;
+
return st_ism330dlc_get_drdy_reg(cdata, &cdata->drdy_reg);
}
diff --git a/drivers/iio/imu/st_ism330dlc/st_ism330dlc_trigger.c b/drivers/iio/imu/st_ism330dlc/st_ism330dlc_trigger.c
index 98038b5..07e887f 100644
--- a/drivers/iio/imu/st_ism330dlc/st_ism330dlc_trigger.c
+++ b/drivers/iio/imu/st_ism330dlc/st_ism330dlc_trigger.c
@@ -132,7 +132,7 @@ int st_ism330dlc_allocate_triggers(struct ism330dlc_data *cdata,
}
err = request_threaded_irq(cdata->irq, NULL, ism330dlc_irq_management,
- IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+ IRQF_TRIGGER_RISING | IRQF_ONESHOT,
cdata->name, cdata);
if (err)
goto deallocate_trigger;
Note: When integrating to new version of kernel as 5.x, need to change api 'get_monotonic_boottime' to 'ktime_get_ts' in a few code statements.
2020-09-16 01:44 AM
Hi @Tdo.1 ,
I'm not an expert of Linux environment, so I'm waiting for internal expert feedback.
You wrote:
>> Linux supported driver for this device (iio/imu/st_lsm6dsx); I added to dts file
Please note however that there are official linux driver at THIS link for the ISM330DLC, especially the st_ism330dlc_i2c.c and st_ism330dlc_i2c_master.c files for the I2C peripheral configuration.
Let me know if they can help you for your purpose.
-Eleon
2020-09-16 11:58 PM
Hi @Eleon BORLINI
Thank you for reply
I integrated driver from your link to my current Linux (5.4.24), it's same result as before. I only can ONESHOT conversions by reading `/sys/bus/iio/devices/iio:device0/in_accel_y_raw`
my dts for ISM330DLC:
ism330dlc@6b {
compatible = "st,ism330dlc";
reg = <0x6b>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ioexp_int>;
interrupt-parent = <&gpio1>;
interrupts = <12 IRQ_TYPE_LEVEL_HIGH>;
st,drdy-int-pin = <1>;
};
I also tested with other IMU as a reference (MPU6050). I connected MPU6050 same as ISM330DLC to board (same I2C, GPIO pin on IMX board) and MPU6050 was worked.
DTS for MPU6050:
inv-mpu6050@68 {
compatible = "invensense,mpu6050";
reg = <0x68>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ioexp_int>;
interrupt-parent = <&gpio1>;
interrupts = <12 IRQ_TYPE_EDGE_RISING>;
mount-matrix = "-0.984807753012208", /* x0 */
"0", /* y0 */
"-0.173648177666930", /* z0 */
"0", /* x1 */
"-1", /* y1 */
"0", /* z1 */
"-0.173648177666930", /* x2 */
"0", /* y2 */
"0.984807753012208"; /* z2 */
};
I'm not sure connector between ISM330DLC and board maybe a problem or no :(
2020-09-17 04:03 AM
Hi @Tdo.1 ,
can you check if the ISM330DLC INT1 or INT2 pins have been routed out on the IMX8MP?
The data ready (DRDY) signal can be for example routed on INT1 physical pin enabling the data ready setting to 1 the INT1_DRDY_XL of INT1_CTRL (0Dh) and writing the DRDY_ON_INT1 bit of MASTER_CONFIG (1Ah) register.
Just to check if it is not an hardware problem...
-Eleon
2020-09-18 02:46 AM
Hi @Eleon BORLINI ,
I connected INT1 pin to a GPIO pin on the IMX8MP.
echo 503 > /sys/class/gpio/export
watch -n 1 cat /sys/class/gpio/gpio503/value
1
2020-09-21 09:02 AM
Resolved:
In my case, I have to do more steps with this driver to resolve issue:
diff --git a/drivers/iio/imu/st_ism330dlc/st_ism330dlc_core.c b/drivers/iio/imu/st_ism330dlc/st_ism330dlc_core.c
index 998d234..d326d74 100644
--- a/drivers/iio/imu/st_ism330dlc/st_ism330dlc_core.c
+++ b/drivers/iio/imu/st_ism330dlc/st_ism330dlc_core.c
@@ -117,6 +117,14 @@
#define ST_ISM330DLC_SELFTEST_FAIL_MS "fail"
#define ST_ISM330DLC_SELFTEST_PASS_MS "pass"
+
+#define ST_ISM330DLC_DRDY_PULSED_ADDR 0x0b
+#define ST_ISM330DLC_DRDY_PULSED_MASK 0x80
+
+#define ST_ISM330DLC_DRDY_ON_INT1_ADDR 0x1a
+#define ST_ISM330DLC_DRDY_ON_INT1_MASK 0x80
+
+
/* CUSTOM VALUES FOR ACCEL SENSOR */
#define ST_ISM330DLC_ACCEL_ODR_ADDR 0x10
#define ST_ISM330DLC_ACCEL_ODR_MASK 0xf0
@@ -1723,10 +1731,10 @@ static int st_ism330dlc_init_sensor(struct ism330dlc_data *cdata)
msleep(200);
/* Latch interrupts */
- err = st_ism330dlc_write_data_with_mask(cdata, ST_ISM330DLC_LIR_ADDR,
- ST_ISM330DLC_LIR_MASK, ST_ISM330DLC_EN_BIT, true);
- if (err < 0)
- return err;
+// err = st_ism330dlc_write_data_with_mask(cdata, ST_ISM330DLC_LIR_ADDR,
+// ST_ISM330DLC_LIR_MASK, ST_ISM330DLC_EN_BIT, true);
+// if (err < 0)
+// return err;
/* Enable BDU for sensors data */
err = st_ism330dlc_write_data_with_mask(cdata, ST_ISM330DLC_BDU_ADDR,
@@ -1741,6 +1749,15 @@ static int st_ism330dlc_init_sensor(struct ism330dlc_data *cdata)
if (err < 0)
return err;
+ /* Enable pulsed data-ready mode */
+ err = st_ism330dlc_write_data_with_mask(cdata,
+ ST_ISM330DLC_DRDY_PULSED_ADDR,
+ ST_ISM330DLC_DRDY_PULSED_MASK,
+ ST_ISM330DLC_EN_BIT, true);
+ if (err < 0)
+ return err;
+
+
/* Redirect INT2 on INT1, all interrupt will be available on INT1 */
err = st_ism330dlc_write_data_with_mask(cdata,
ST_ISM330DLC_INT2_ON_INT1_ADDR,
@@ -1749,6 +1766,14 @@ static int st_ism330dlc_init_sensor(struct ism330dlc_data *cdata)
if (err < 0)
return err;
+ /* Enable master DRDY on INT1 */
+ err = st_ism330dlc_write_data_with_mask(cdata,
+ ST_ISM330DLC_DRDY_ON_INT1_ADDR,
+ ST_ISM330DLC_DRDY_ON_INT1_MASK,
+ ST_ISM330DLC_EN_BIT, true);
+ if (err < 0)
+ return err;
+
return st_ism330dlc_get_drdy_reg(cdata, &cdata->drdy_reg);
}
diff --git a/drivers/iio/imu/st_ism330dlc/st_ism330dlc_trigger.c b/drivers/iio/imu/st_ism330dlc/st_ism330dlc_trigger.c
index 98038b5..07e887f 100644
--- a/drivers/iio/imu/st_ism330dlc/st_ism330dlc_trigger.c
+++ b/drivers/iio/imu/st_ism330dlc/st_ism330dlc_trigger.c
@@ -132,7 +132,7 @@ int st_ism330dlc_allocate_triggers(struct ism330dlc_data *cdata,
}
err = request_threaded_irq(cdata->irq, NULL, ism330dlc_irq_management,
- IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+ IRQF_TRIGGER_RISING | IRQF_ONESHOT,
cdata->name, cdata);
if (err)
goto deallocate_trigger;
Note: When integrating to new version of kernel as 5.x, need to change api 'get_monotonic_boottime' to 'ktime_get_ts' in a few code statements.
2020-09-22 12:27 AM
Hi @Tdo.1 ,
thank you very much for your follow up on resolved case :smiling_face_with_smiling_eyes:
...and sorry for coming back to you late.
-Eleon