Hi all
I made a cape Board for the AI64 that has a I2C interface with icm20948 (Invensense,IMU).
i assign the default pin I2C2 (P9.19,P9,20) for SCL and SDA for icm20948 interface.
i made dts file for BONE-I2C2,dts below.
Failing that, you can talk to the chip from userspace using the i2c dev driver.
Given that the above kernel driver only polls the chip, you would be no worse off reading it yourself from userspace.
Thank you for your fast response.
I am quite new with embdded linux and beaglebone AI64.
Do you mean i need to build kernel with reference the sources?(or just build and add?)
i need more information to reference the git driver source and kernel build.
my kernel version is 5.10.168-ti-arm64-r113.
the polling only code
$ make
make -C /lib/modules/5.10.168-ti-arm64-r113/build M=/home/debian/icm20948-mod modules
make[1]: Entering directory β/lib/modules/5.10.168-ti-arm64-r113/buildβ
make[1]: *** No rule to make target βmodulesβ. Stop.
That will be a problem. Looking at the datasheet, looks like the minimum logic high voltage is stated as 2V for the BBB i/o pins . It looks like the AM3358 itself could be designed to use 1.8V i/o logic rather than 3.3V, , but that doesnβt help you any.
The -C option should be the path to the kernel source - is that true ? I suspect that is why the make is failing.
It is a bit irrelevant as I donβt think you will get that chip to work. I would look for something that is compatible with 3.3V logic.
That table is confusing, and the datasheet on the chip is very long and not so easy to find information. The schematic shows power fo VDDSHV0 - 4 as being 3.3V, VDDSHV6 as 1.8V. So unless you can configure on a pin by pin basic what power domain it is connected to, you are stuck with what you have.
The pin multiplexing on describes the different peripherals/functions for pins and does not mention changing the power domain. I suspect you canβt. It would be dangerous in any case.
You might find it easier to connect the chip using SPI rather than I2C. You will need level shifters of course, but you donβt need to worry about the bidirectional open drain nature of I2C
and the levelshifter what i use has internal 10k pull up and when i checked the impedance was 5.x(10k//10k)
I will check next week with setting dtsi as
Hi
now
debian@BeagleBone:~$ ls /sys/bus/i2c/devices
2-0050 4-0047 i2c-0 i2c-2 i2c-4 i2c-6
2-0051 5-0068 i2c-1 i2c-3 i2c-5 i2c-7
i think 5-0068 is the ICM20948
icm20948_mod
after install kernel headers :sudo apt-get install linux-headers-$(uname -r)
i can see code error of make ,and after debug ,i can see icm20948.ko
debian@BeagleBone:~/Downloads/icm20948-mod$ sudo insmod icm20948.ko
debian@BeagleBone:~/Downloads/icm20948-mod$ lsmod | grep icm20948
icm20948 20480 0
but fail to write
debian@BeagleBone:~/Downloads/icm20948-mod$ cat /var/log/syslog | grep icm20948
Jan 16 07:46:04 BeagleBone test_ICM20948: Failed to write 00 to device: 68, address: 7f.
Jan 16 07:46:04 BeagleBone test_ICM20948: Failed to write request to device: 68, address: 00 in order to olscat /varbtain data.
β add 0x7f is a register bank ,acces fail
β add 0x00 who am i ,access fail
The pull-ups are not that critical. The internal resistors are fine for a slow speed I2C bus. If you are going faster you might want to add some extra resistors to give an overall lower pull-up resistance.
Are you loading the overlay for the I2C2 bus ? Is it enabled by default ?
Also your overlay file does not look right to me. Where is bone_i2c_imu defined and associated with the correct I2C bus ?
As a first step I would check to make sure there are actual I2C signals on the pins. Have you got access to a scope.?
Write a simple Python program to read from the I2C bus so you can generate signals on demand and check the I2C pins. Setup the scope to trigger on the clock pin.
If the check has a status register, just try reading that. Compare it to the reset state.
bus = smbus.SMBus(5) # 1 indicates /dev/i2c-5
DEVICE_ADDRESS = 0x68 # Replace with deviceβs address
STATUS_REG = 0x19 # status registerβs address
def read_status_register():
βββReads data from the status register.βββ
try:
# Read a single byte from the specified register
status = bus.read_byte_data(DEVICE_ADDRESS, STATUS_REG)
return status
except Exception as e:
print(f"Error: {e}")
return None
def main():
while True:
status = read_status_register()
if status is not None:
print(f"Status Register: {status}")
time.sleep(1)
if name == βmainβ:
main()
result
Status Register:128
Status Register:0
Status Register:0
Status Register:0
and i changed 0x00
i can see 0xEA same as described in spec
Ok that looks good, so the hardware is fine and doing what it should. The ICM20948 must be responding with an ACK or you would have seen an error I think.
That just leaves the driver.
Depending on your needs there are quite a few options.
You could just talk to the chip directly yourself using the I2Cdev driver
2 .You can get the kernel module working.
As you are on the AI64 you could also write code to run on one of the R4 or PRU cores to read the IMU.
Really going to depend on what you are using it for and how fast you need to get the data. option 1 is probably the easiest as it will be easier to test and debug. Option 3 the hardest, especially as there is very little documentation for doing that. A couple of people here have managed to get code running on the R4 & PRU cores though.