cancel
Showing results for 
Search instead for 
Did you mean: 

Can only read/write to certain LSM6DSOX registers via SPI from raspberry Pi

AM.10
Associate

I'm having trouble reading and writing to my Adafruit LSM6DSOX IMU from my Raspberry Pi 4 running Ubuntu 20.04. I need to do it via SPI since I require the bandwidth, but I can only seem to read the WHO_AM_I register successfully. Other registers (see below) either returns junk data or 0x00. I have verified that I can read data off the IMU from an Arduino via SPI, so its likely some software issue. Any insight/ideas what could be causing this would be greatly appreciated!

I can read the following registers:

0x0f : 0x6c

0x13 : 0x1c

0x33 : 0x1c

0x53 : 0x1c

0x73 : 0x1c

These are all random registers however, and the value 0x1C doesn't seem to correspond with anything. In fact, CTRL4_C (0x13) is defined as having bit 5=0, so the value being read shouldn't even be possible...

My main.py:

import LSM6DSOX
 
def main():
    imu=LSM6DSOX.LSM6DSOX()
    imu.initSPI()
 
 
    whoamI=imu.read_reg(0x0F)
    while(whoamI != imu.LSM6DSOX_ID):
        imu.ms_sleep(200)
        print('searching for IMU')
        whoamI=imu.get_id()
        print(hex(whoamI))
    print('found lsm6dsox IMU')
 
    imu.spi.close()
    imu.spi = None
 
if __name__=="__main__":
    main()

An excerpt of my LSM6DSOX.py:

    def initSPI(self):
        # Setup communication SPI
        self.spi = spidev.SpiDev()
        self.spi.open(0, 0)
        self.spi.mode=0b11 #mode 3, (mode 0 is also fine)
        self.spi.max_speed_hz = 500000
        return self.spi
 
    def read_reg(self, reg, len=1):
        # Set up message 
        buf = bytearray(len+1)
        buf[0] = 0b10000000 | reg # MSB bit must be 1 to indicate a read operation. this is OR'd with the register address you want to read
 
        resp =self.spi.xfer2(buf) #send (and recieve) data to the imu
        if len==1:
            return resp[1]
        else:
            return resp[1:] #display recieved data
 
    def write_reg(self, reg, data, len=1):
        # Set up message 
        buf = bytearray(len+1)
        buf[0] = 0b00000000 | reg # MSB bit must be 0 to indicate a read operation. this is OR'd with the register address you want to read
        buf[1:] =bytes(data)
        resp =self.spi.xfer2(buf) #send (and recieve) data to the imu
        return resp[1:] #display recieved data 

2 REPLIES 2
Eleon BORLINI
ST Employee

Hi @AM.10​ ,

are you correctly configuring the SPI multiread (in case you are using it and not a loop of single SPI shots)? See the datasheet p.22, for more info.

If not, you might see correctly see only the first read register, but wrong values on the next ones.

-Eleon

AM.10
Associate

Hi Eleon,

Thank you for your reply! I was going to use my read/write function for multiple byte transfers, but reading 1 Byte of data requires sending 2 bytes if I understand correctly. 1 Byte is sent with the RW bit and address, and then during the following byte the data is sent (in the case of a read). And between these two bits the CS pin should be held low throughout. Am I understanding any of that wrong?

Best,

Andy