Josh Leverette's blog

Josh Leverette's picture

Busy days

Today was not as productive as I wanted it to be. I will be doing checkout dives as the final stage of my open water SCUBA certification over the next two days, so I expect I won't have much time to be productive then, but I will certainly try.

On the bright side, it seems that a minimal LSM9DS0 driver is imminent. There really isn't much left to do to get the basics working if things go according to plan, and then I can add more features over time as needed. But, the real fun will start after that, since I'll be able to begin crunching numbers for real-time positioning data, hopefully.

Josh Leverette's picture

Applying the DLA to my system

Today, I applied my DLA (digital logic analyzer) to the Nucleo/LSM9DS0 circuit to see how my I2C HAL is holding up.

I've attached screenshots of Logic showing the waveforms from the I2C operations. The write operation worked perfectly, as expected, with all of the proper ACKs coming from the LSM9DS0.

I was more concerned about how the reading would work, since I was uncertain whether that truly could work within the I2C spec. I'm pleased to report that it seems to have worked just fine! In I2Cread.jpg, you'll notice that there is a large empty block. I artificially induced some delay there so that it would be clear as to which waveforms belonged to which actions. I first wrote into 0x20 with a value of 0xF8. After the delay, I then read that value back out. The read process works by writing a single byte representing the register address, then sending a read command. 0xF8 came out on the other side, so it seems to have worked just fine.

Josh Leverette's picture

More initialization, more constants

I continued hammering out the LSM9DS0 initialization logic, and adding necessary constant macros.

Right now, everything is being implemented through an interface independent "API" consisting of a register write method, and a register read method. This has allowed me to postpone actually testing the I2C code implemented within those two methods. I'm tentatively planning to test the I2C code tomorrow, and pull out my Saleae digital logic analyzer to watch the bits flow and see what goes wrong -- to see what needs to be fixed.

Josh Leverette's picture

Bootstrap logic

Today, I focused primarily on filling out the LSM9DS0 header with macros for useful constants, and working on setting up the LSM9DS0 constructor to do the proper bootstrap logic to turn on the LSM9DS0 and give it a sane initial configuration.

Made quite a bit of progress, and I feel like I have a deepening understanding of how the device is meant to be viewed from an embedded programming standpoint. As always, the code is on my GitHub.

Josh Leverette's picture

Protocol comprehension, at last!

Sometimes, if you stare at something too hard it is difficult to understand what you're looking at. This was the case with the LSM9DS0's documentation on the I2C protocol being used. I can now say pretty confidently that I understand how that communication works. It was confusing before because the device seemed to claim at least 8 different I2C addresses to itself, yet it only seemed to respond to two of the addresses when running a little I2C scanner.

The LSM9DS0 has one pin dedicated to letting you change the address of the sensor! This is useful, especially if you happen to have two I2C devices that overlap in address, or if you want to use more than one LSM9DS0 in a single system, which is something that I may investigate later this summer if I can't get the accuracy I need from a single LSM9DS0. I'm really impressed with that simple, but useful feature.

So, this means that the LSM9DS0 actually only claims 4 addresses at a time. Two addresses are for writing, and two are for reading. One pair connects to the accelerometer and the magnetometer, apparently, and another pair connects to the gyroscope. I've learned that affecting the address's Least Significant Bit is standard procedure for letting an I2C device know whether it is being written to or read from.

So, now the different addresses are understood. The datasheet also has some useful protocol diagrams, so I understand what order bytes are supposed to be written to and read from in regards to the data line, in order to read and write to the LSM9DS0. I need to determine if that protocol actually meshes with the standard I2C functions, but I think it does.

After this, I can hopefully combine my notes from earlier on the various registers and such to be able to communicate successfully. It looks likely, at least.

Josh Leverette's picture

Continued Progress

Today, I continued learning about the LSM9DS0 protocol, but some friends came into town and it was not nearly as productive of a day as I had hoped it would be. Tomorrow is looking like I'm going to hopefully buckle down and get some serious stuff done.

Josh Leverette's picture

Progress on I2C

This evening I made more progress on the I2C stuff. I had a little trouble finding where in the documentation it even listed the I2C address of the device, so I scanned all possible I2C addresses and found 3A and D6. Using that knowledge, I was able to quickly find the page in the documentation that discussed it. Work is under way to begin communicating with the LSM9DS0.

Josh Leverette's picture

Adventures with I2C

For now, it's looking like I'm going to be using I2C to communicate with the LSM9DS0. I'm using mbed's I2C driver, since there's no need to duplicate that effort, as interesting as it might be.

At first, my digital logic analyzer was showing nothing happening on SDA and SCL, which was not good. I began testing things more thoroughly and still not getting anywhere.

Eventually, I found an I2C tutorial on the internet that mentioned the necessity of having pullup resistors -- this solved the problem rather instantaneously, and was definitely a "well, duh" moment. I've never used I2C before, but I have read enough documentation on it in the past that I should have known it required pull up resistors, but it had somehow slipped my mind.

I also configured a shared folder between my virtual machine running Ubuntu and my Mac mini, since USB seems to have stopped working on my VirtualBox. I wrote a minimal bash script that runs on the Mac side and serves only to move *.bin files from that shared folder onto the Nucleo so it can be re-imaged. There's also a decent probability that while I had written code yesterday, I don't think I had pushed it up to my GitHub repo. The code still doesn't do much communicating with the LSM9DS0, but the groundwork is being laid pretty steadily.

Josh Leverette's picture

A more productive day

Today I made forward progress on the actual code, setting up the LSM9DS0 class and a few other related things. I'm also pleased that my development environment seems to be functional. I had previously been using a different computer for development with the STM32 Nucleo.

Josh Leverette's picture

Continued work

I have my dev machine configured with the right toolchain, I created a new mbed project, and began getting things ready. Today was not as productive as I had hoped it would be, but that was just because I generally couldn't focus on anything. I still tried to spend some time learning about everything, but I hope to be more focused tomorrow.

Syndicate content