-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
drivers: add driver for Honeywell HMC5883L magnetometer #10083
Conversation
I just ordered some HMC5883L devices to read the gas meter in my flat. Will give this PR a review and test as soon as they arrive (hopefully during the next 2 weeks). |
@haukepetersen Sounds good and it would be really great, but are we talking about the same thing? HMC5883L is a three axis compass. The use case for the use of a compass for reading gas meters is not clear to me. |
Yes, we are talking about the same thing :-) Gas meters in Germany (at least a subset of them) have their least significant digit, this analog spin wheel, encoded with a magnet at one position. So when this digit wheel spins around, you can use the HMC5883L to detect the change in magenetic flux and with that detect a revolution of the digit wheel... So at least in theory, I will let you know if it works in practice for me :-) -> see https://www.kompf.de/tech/gascountmag.html for more info |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just looked briefly through the code without going into too much detail yet. In general everything is straight forward, but I think there are some things we could improve on:
- the
_set_reg_bit()
and_get_reg_bit()
functions seem very strange to me. I don't think they are needed at all. See inline comments for a proposal to remove them - I think I would move the handling for the
DRDY
pin inside of the driver: initialize that GPIO pin if the configuration sets it to something different thanGPIO_UNDEF
. Also we could build a convenience function forread_blocking()
or similar, that blocks until a sample is ready. Maybe even put all of this into a pseudo-sub-module, so its only compiled in if needed/wanted. - using these preprocessor functions/shortcuts would not be my personal style (and its not done too often in the RIOT code base), but this is merely subjective I guess :-)
@haukepetersen Thanks for your first review. |
Principially, I agree that is easy to OR individual bits using corresponding enum values. The same is true for reading. However, for multiple bit values, you would need to define a mask and a shift value for each register member, for example
From my point of view, using these functions allows more readable source code, especially when many multi-bit register values need to be set.
Ok, these functions should be called
Good idea, I will try it in that way. There are other drivers where I did it exactly in that way.
Defining The same is true for RIOT/drivers/vl53l1x/vl53l1x.c Lines 610 to 655 in 39c3406
I know that macros should be used wisely according to the Guidelines for RIOT programming. However, in this particular case, the code size is not affected. Even more, it helps to keep the source code readable. |
I don't see the need for shifting here. All bit positions are static, so it all boils down to OR and NOT AND operations for setting and clearing. For multi-bit values there is further no need to set the bits inidividually, they can be applied 'at-once' using their static values. |
After thinking about the options, I would prefer an approach as it is realized in ADS101X driver. The driver defines a function by which the interrupt is enabled. The function is called by the application and has a callback function as parameters. Defining a blocking function would require to use any synchronization mechanism like message passing or thread flags which seems to be too complex for a low level driver. The problem is that all of our sensor drivers only realize the polling approach so that we have no examples for best practice. But using the callback mechanism for sensor interrupts should be ok. |
@haukepetersen While thinking about the complexity the driver should have for interrupt handling, I am becoming unsure what the best approach is. This is probably a problem we will have with all drivers that require I2C access while handling interrupts. The simplest approach from the driver's point of view would be for the driver to call back the application code directly from the ISR. However, this would be done in the interrupt context. That is, mutexes for synchronizing access to the I2C bus will not work and the application would have to take care of it. Another approach would be to immediately return from the ISR and to call back the application later in the thread context. For this purpose, we introduced the "Single Interrupt Thread", which serializes interrupt events from various drivers that need to access I2C, for example. However, this approach costs an additional thread. What do you think? |
bf0682a
to
c6f6e1d
Compare
@haukepetersen Fixed most of the issues. Please take a look at how the interrupt handling is now realized. I tested the driver again and it still seems to work. The remaining open point is the question of what to do with the macros. While you do not like macros, I like them a lot because they help avoid writing down dozens of copies of the same code over and over again. |
The optional interrupt handling via callback function looks nice, just what I had mind :-) I hope my devices arrive soon, can't wait to try it out! |
ping @haukepetersen |
Btw.: Is there anything that needs to be done for this chip to show up?
|
It might be a problem of your module. I get the following output where
|
a94ed9b
to
3745cb5
Compare
I have just rebased to resolve conflicts. Furthermore, I have removed the dependency of this driver from `xtimer'. |
@haukepetersen were your comments addressed? |
Looks like you've addresses all comments - please squash. |
3745cb5
to
e51b77b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The driver looks good!
Just one place where you can save a bit of ROM and a few minor style nits.
You can squash directly.
Squashed. How do we continue, it is still blocked by @haukepetersen? |
Please squash! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code looks good to me.
Can you provide the output of |
9edcbc8
to
e9c0f76
Compare
Squashed. The output is:
|
Contribution description
This PR adds a driver for the Honeywell HMC5883L 3-axis digital magnometer as it is used for example on GY-85 9-DOF (Accelerometer ADXL345, Gyroscope ITG3200, Magnetometer HMC5883) module. Honeywell HMC5883L is a very easy to use, ultra-low-power magnetometer.
The driver implements
Testing procedure
This PR includes
tests/driver_hmc5883l
which can be used for testing. This test application demonstrates the usage of the driver and shows the different approaches to fetch data, by using eitherhmc5883l_read function
at a lower rate than the the DOR, or