drivers: add driver for APDS99XX ambient light and proximity sensors#10420
drivers: add driver for APDS99XX ambient light and proximity sensors#10420aabadie merged 4 commits intoRIOT-OS:masterfrom
Conversation
0edd9e3 to
22f035b
Compare
leandrolanzieri
left a comment
There was a problem hiding this comment.
Nice work! Here are some comments, I'm still reviewing it though, it's a pretty big driver. I will also try to get a sensor to test this.
drivers/apds99xx/apds99xx.c
Outdated
| #else | ||
| EXEC_RET(_reg_write(dev, APDS99XX_REG_PPCOUNT, &dev->params.prx_pulses, 1)); | ||
| EXEC_RET(_update_reg(dev, APDS99XX_REG_CONTROL, APDS99XX_REG_PDIODE, 2)); | ||
| #endif |
There was a problem hiding this comment.
Here and above, please add the comment of the corresponding tag (/* MODULE_APDS9960 */)
drivers/apds99xx/apds99xx.c
Outdated
| __func__, d->params.dev, APDS99XX_I2C_ADDRESS, ## __VA_ARGS__); | ||
|
|
||
| #define EXEC_RET(f) { \ | ||
| int _r; \ |
There was a problem hiding this comment.
It would be better not to assign the value to _r inside of the if statement. Also, is the intermediate variable really needed here and below?
There was a problem hiding this comment.
Thanks for your review.
It would be better not to assign the value to _r inside of the if statement.
I'm wondering why? What is the reason.
Also, is the intermediate variable really needed here and below?
Yes, if we want to print out the error code in the debug message.
But more important, we have to return the error code we got from executed function in case of error.
leandrolanzieri
left a comment
There was a problem hiding this comment.
Just some little comments, otherwise looks good. I don't think I will be getting the sensor in time for testing this for the feature freeze. @aabadie any chances you could?
|
FWIW: I am currently running the provided tests with an APDS 9960. Both, the basic (polling) version as well as the int-controlled version seem to work as expected. (Did not check the color values, though.) |
|
@leandrolanzieri Thanks for reviewing. |
|
Hello Everyone |
| double ga = 0.49; /* glas or lens attenuation factor */ | ||
| double b = 1.862; | ||
| double c = 0.746; | ||
| double d = 1.291; |
There was a problem hiding this comment.
If you multiply them all by 1000, you wouldn't need to use double here, no?
dismissed stale review after 1 year
|
Please rebase, I have the hardware to test this PR (apds9960) :) |
b5771d1 to
7584760
Compare
tests/driver_apds99xx_full/main.c
Outdated
| apds99xx_t dev; | ||
|
|
||
| /* save the reference to the main thread */ | ||
| t_main = (thread_t*)sched_threads[sched_active_pid]; |
There was a problem hiding this comment.
better use t_main = thread_getpid(); here?
There was a problem hiding this comment.
The reference to the main thread is required in apds99xx_isr. Using thread_get(pid) doesn't work since it replaces the const attribute.
I changed the interrupt handling to a mutex based approach.
drivers/apds99xx/apds99xx.c
Outdated
| #endif | ||
|
|
||
| /* wait for 6 ms after power on reset */ | ||
| xtimer_usleep(6 * US_PER_MS); |
There was a problem hiding this comment.
would be nice to get rid of xtimer usage, especially as this is the only one. Isn't there a state register or gpio that we could poll (while(...) {} style) instead?
There was a problem hiding this comment.
The problem is that this time is specified in the data sheet. It is the time the sensor needs for initialization after power-on to become ready for operation. Unfortunately there is no status flag.
Possible solutions:
-
We simply assume that RIOT takes longer to load than this 6 ms before the device is accessed for the first time.
-
We allow multiple tries of the
_is_availablefunction and use the I2C ACK to determine when the device is available. However, at an I2C speed of 400 kbps, each failed attempt on the bus would only take 0.025 ms, which could mean a maximum of 250 failed attempts for 6 ms.
There was a problem hiding this comment.
I have removed the dependency on xtimer with commit d909fad.
aabadie
left a comment
There was a problem hiding this comment.
I found some minor typos and small issues in the Python scripts (as reported by the CI).
Maybe also add ALS ==> ALSO in the list of codespell ignored words.
I'll give this PR a try later today.
|
Also: please rebase :) |
|
I could test this PR on the adafruit-clue board (after some rebase and fix of conflicts). This board embeds an apds9960 variant. Here is what I get:
|
@aabadie Do you see ALS measurements? If yes, interrupts are working since these measurements use the data ready interrupt. The proximity interrupt is triggered, when the proximity value exceeds 200 counts. This happens at a distance of about 2 cm. In that case, the output also shows the proximity value, for example: |
f75e78d to
b6e8ca9
Compare
Thanks! I'll have a look and test again tomorrow. |
|
Tested this PR again this morning on adafruit-clue and I can't have the interrupt based test application to work. If I comment out the I trust you that this test is working anyway. |
The Adafruit-Clue seems to be a very interesting board. According to the schematic |
I had the same idea and tried to invert the pins but it didn't work either. I won't block this PR because of this anyway. |
|
I think we are good with this one. @gschorcht, please squash! |
e372058 to
bd3ccc4
Compare
|
Thank you all for reviewing and testing. BTW, I hope I can implement the gesture recognition function of APDS9960 in next week. I will provide it as separate PR. |
Contribution description
This PR adds a driver for Broadcom APDS99XX ambient light and proximity sensor series. It supports the following sensors:
apds9900apds9901apds9930apds9950apds9960The driver variants for the various sensors are defined as pseudomodules. To use the driver, the sensor used must be specified by the application by one of these pseudomodules, e.g.,
The driver functionality is divided in two parts:
Basic driver
apds99xxThe base driver
apds99xxonly supports a basic set of functions and has therefore a smaller size. The procedure for retrieving new data is polling. Ambient light and proximity sensing are supported.Fully functional driver
apds99xx_fullThe fully functional driver
apds99xx_fullsupports all the features supported by the base driver, as well as all other sensor features, including interrupts and their configuration. Data-ready interrupts can be used to retrieve data. In addition, threshold interrupts can be used and configured.For each of the two driver variants there is a corresponding test application:
tests/driver_apds99xxandtests/driver_apds99xx_full.The basic driver
apds99xxis automatically enabled when the driver variant for the used sensor is specicied.Testing procedure
To test the driver, the test application can be used without interrupts as following
or with interrupt
where the sensor used has be specified accordingly in the
USEMODULEstatement.Issues/PRs references
Fixes issue #10164