Skip to content

Conversation

@Rubusch
Copy link

@Rubusch Rubusch commented Feb 11, 2025

Hello Zepherinos!

The ADXL345 accelerometer sensor was not showing up any values, if there was no trigger with FIFO configured. In such case the sensor falls back to FIFO bypass mode and usually still shows measurements, but does not provide events (data ready, fifo, single tap, double tap, free fall, activity/inactivy). The patch fixes the issue, and makes the sensor interface show data again when no trigger is configure.

Since this is my first zephyr series, I hope this matches the procedure to submit and contribute to the project. Please, don't hesitate to let me know if anything is missing here.

Signed-off-by: Lothar Rubusch [email protected]

@zephyrbot zephyrbot added area: Sensors Sensors platform: ADI Analog Devices, Inc. labels Feb 11, 2025
@github-actions
Copy link

Hello @Rubusch, and thank you very much for your first pull request to the Zephyr project!
Our Continuous Integration pipeline will execute a series of checks on your Pull Request commit messages and code, and you are expected to address any failures by updating the PR. Please take a look at our commit message guidelines to find out how to format your commit messages, and at our contribution workflow to understand how to update your Pull Request. If you haven't already, please make sure to review the project's Contributor Expectations and update (by amending and force-pushing the commits) your pull request if necessary.
If you are stuck or need help please join us on Discord and ask your question there. Additionally, you can escalate the review when applicable. 😊

yperess
yperess previously approved these changes Feb 18, 2025
Copy link
Contributor

@yperess yperess left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving, but highly recommend to take a second look at this driver.

Copy link
Member

@MaureenHelm MaureenHelm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dimitrije-lilic can you take a look?

@dimitrije-lilic
Copy link
Contributor

Hi all,
I took base driver and was working on implementing rtio streaming, haven't looked in more detail other modes (except watermark trigger) i agree that bypass needs to be revisited, and also finer differentiation between trigger and streaming (as sensor modes) and rtio streaming which is causing confusion. I took a look at this changes and i agree the there shouldn't be hardcoded values but need a little time more to investigate

@Rubusch
Copy link
Author

Rubusch commented Feb 20, 2025

@dimitrije-lilic thank you for answering. I know this is a bit "pushy" now. Would you mind to approve to this pull request, or if reject, please let me know what I could improve? :)

I mean, these are just 3 very limited commits.. I could come up with something more thorough in a follow up. But I did not want to interfere with someone's work. So, if you (or any of you guys) already planned to do a general brush up to this ADXL345 zephyr driver?

Comment on lines 333 to 345
if (data->fifo_config.fifo_mode == ADXL345_FIFO_BYPASSED) {
rc = adxl345_read_sample(dev, &sample);
if (rc < 0) {
LOG_ERR("Failed to read sample rc=%d", rc);
return rc;
}

data->bufx[0] = sample.x;
data->bufy[0] = sample.y;
data->bufz[0] = sample.z;

return 0;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be more intuitive to conditionally read samples_count if in FIFO mode, otherwise set samples_count to 1. Then proceed with the existing adxl345_read_sample logic.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @MaureenHelm - Thank you so much! This Feedback helps. I will have a look and resubmit until, say, mid march (I'm currently travelling, and mostly offline).

Copy link
Author

@Rubusch Rubusch Mar 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I changed this a bit. Note, I'm reading samples_count from FIFO status register for all other modes than focus would move rather to the source default fallback is not 1 for BYPASSED. I left a comment on that. FIFO bypassed is the only mode actually bypassing the FIFO, i.e. not having a FIFO, neither FIFO events and thus actually won't have FIFO status register entries do evaluate, such as sample_count.

return -EIO;
}

#ifdef CONFIG_ADXL345_TRIGGER
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree this should not be hardcoded, remove the whole ifdef, suggested code:
rc = adxl345_configure_fifo(dev, cfg->fifo_config.fifo_mode, cfg->fifo_config.fifo_trigger, cfg->fifo_config.fifo_samples);

Also in the config default mode should be:
#define ADXL345_CONFIG(inst)
.fifo_config.fifo_mode = ADXL345_FIFO_BYPASSED, \

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @dimitrije-lilic - first of all, thank you so much for this feedback! I really appreciate, and updated the stance. Really good advice, thanks again. Pls, if you can find some time, have a look at it.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a note, I separated setting the default fifo_mode to a separate commit. IMHO the original patch series was supposed to fix bypass mode more or less. Changing what is the default fifo mode is not quite the same, thus separate patch. If you guys disagree, pls let me know.

struct adxl345_dev_data *data = dev->data;
uint8_t dev_id;
bool is_full_res = true;
#ifdef CONFIG_ADXL345_TRIGGER
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove ifdef just leave config because it is going to be used now

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok.

@Rubusch
Copy link
Author

Rubusch commented Mar 16, 2025

[I'm unsure if this is the right place to discuss this, or better switch to discord on sensors / adi, pls let me know?]

Stupid Question: Why not making all the #ifdef ADXL345_FIFO_STREAMED and #ifdef ADXL345_FIFO_TRIGGERED dependent purely on the DTS? I mean, having something like a gpios-int1 or gpios-int2 property in the DTS enables, say, STREAM by default; where neither having gpios-int1 nor gpios-int2 falls back to BYPASSED. If then, really needed to distinguish between a FIFO STREAM mode and a dedicated FIFO_TRIGGERED mode (IMHO even the STREAM mode was fully sufficient for working with the FIFO events) this could be rather an additional DTS label.

I see advantages in...

  • It could be configured right away over the bindings.
  • It would remove a lot of preprocessor #if_def/#else/#endif mess, thus result in a cleaner code.
  • It would remove (then actually) unnecessary Kconfig options. From a maintenance aspect this could ease up the work with this driver, since all is in the source. I mean, there will be a Kconfig context needed, for in case ASYNC, RTIO, etc anyway, but I'd rather not introduce, means, remove particular additional ADXL345_ Kconfig options.

I'm unsure if this makes sense in this case for Zephyr. I can see, that DTS shall describe hardware, but TBH a FIFO mode is pretty fixed to the setup, and would not change. If the interrupt is wired, and the sensor supposed to work in STREAM mode, it would definitely be describing hardware, thus a case for DTS.

@yperess
Copy link
Contributor

yperess commented Mar 16, 2025

[I'm unsure if this is the right place to discuss this, or better switch to discord on sensors / adi, pls let me know?]

Stupid Question: Why not making all the #ifdef ADXL345_FIFO_STREAMED and #ifdef ADXL345_FIFO_TRIGGERED dependent purely on the DTS? I mean, having something like a gpios-int1 or gpios-int2 property in the DTS enables, say, STREAM by default; where neither having gpios-int1 nor gpios-int2 falls back to BYPASSED. If then, really needed to distinguish between a FIFO STREAM mode and a dedicated FIFO_TRIGGERED mode (IMHO even the STREAM mode was fully sufficient for working with the FIFO events) this could be rather an additional DTS label.

I see advantages in...

  • It could be configured right away over the bindings.
  • It would remove a lot of preprocessor #if_def/#else/#endif mess, thus result in a cleaner code.
  • It would remove (then actually) unnecessary Kconfig options. From a maintenance aspect this could ease up the work with this driver, since all is in the source. I mean, there will be a Kconfig context needed, for in case ASYNC, RTIO, etc anyway, but I'd rather not introduce, means, remove particular additional ADXL345_ Kconfig options.

I'm unsure if this makes sense in this case for Zephyr. I can see, that DTS shall describe hardware, but TBH a FIFO mode is pretty fixed to the setup, and would not change. If the interrupt is wired, and the sensor supposed to work in STREAM mode, it would definitely be describing hardware, thus a case for DTS.

I think the answer is related to downstream users. Imagine that you had a board with a sensor and you configured all the DTS attributes to add the interrupt lines in upstream Zephyr. But a downstream application doesn't want to use streaming APIs. Instead of having to modify the devicetree node in an overlay, they can just disable the Kconfig.

Copy link
Contributor

@yperess yperess left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall this driver breaks the sensor API and should really just not support FIFO mode without the ASYNC API. fetch/get are meant to only support the "latest sample".

At a minimum, lets fix the initialization so it's using a devicetree binding enum instead of a kconfig which is a global value.

At best, this driver should implement the RTIO submit call for the FIFO.

Comment on lines 466 to 477
if (IS_ENABLED(CONFIG_ADXL345_TRIGGER)) {
fifo_mode = ADXL345_FIFO_TRIGGERED;
} else if (IS_ENABLED(CONFIG_ADXL345_STREAM)) {
fifo_mode = ADXL345_FIFO_STREAMED;

rc = adxl345_reg_write_byte(dev, ADXL345_FIFO_CTL_REG,
ADXL345_FIFO_STREAM_MODE);
if (rc < 0) {
LOG_ERR("FIFO enable failed\n");
return -EIO;
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't good, if you had 2 of these sensors attached and you wanted one to use the streaming mode and the other bypass you'd end up with both using streaming. You should add to the dts binding an enum for fifo-mode: [bypass, trigger, stream] and save the devicetree value in the config. Then use that in the init function.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand you correctly this supports actually my idea I tried also to explain before i.e. to have the FIFO mode selection rather entirely over DTS, and remove the Kconfig related options. TBH I did not think of several sensors connected, but this is probably the strongest argument for DT binding.

I'll prepare the following TODOs

  • FIFO mode selection entirely over DT binding
  • RTIO submit call for the FIFO

Copy link
Author

@Rubusch Rubusch Apr 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, some days have passed. So far I can come up with an approach implementing TRIGGER mode based on a defined
GPIO line #1 or #2 in the DTS, and dealing with data ready, watermark and overrun events.

It will then set up Analog's "FIFO_STREAM" mode, and allow for optional registering callbacks for data ready,
watermark and/or overrun events. If none are provided, the FIFO is flushed to recover for re-generating new
interrupt events. Also, TRIGGER mode w/o defined GPIO lines is possible. Then it falls back to Analog's
"FIFO BYPASSED" mode. This is also the default mode if TRIGGER / ASYNC API is not configured.
RTIO is still a topic for me. It works +/- but I'd like to exclude it for now, and push this later. I'm still
around fixing and need a better understanding of it to be confident.

Basically I'm unsure if the pull request is still open, or if someone already took care of it. If still
open as it looks to me by current git history, I'd love to clean up, split into reasonable commits, check them
and and I will probably push an update within the next days.

@Rubusch Rubusch force-pushed the lothar/adxl345-v0.02 branch 2 times, most recently from 0cb1805 to d1edd74 Compare April 19, 2025 20:31
@Rubusch
Copy link
Author

Rubusch commented Apr 19, 2025

The current approach implements fetch & get with TRIGGER support to operate the sensor FIFO. One of two GPIO lines is configurable in the DTS now. The driver will map the according interrupt line for the sensor events. FIFO related sensor events are data ready, watermark and overrun. Each event allows for registering a handler from the application. The TRIGGER mechanism catches the sensor interrupts and also can flush the FIFO and reset the interrupt status register. The FIFO watermark (as also before the ODR) is configurable from an app by the set attr function.

The FIFO works either in FIFO_BYPASS mode, when no zephyr TRIGGER (or STREAM) is configured, or when TRIGGER is configured, but no GPIO lines are defined in the DTS. If zephyr's TRIGGER is configured, the FIFO will operate in Analogs FIFO_STREAM mode [Note, there is Analog's FIFO_TRIGGER mode and there is TRIGGER in a zephyr context, I try to make it a bit clear here, I'm not talking about Analog's FIFO_TRIGGER mode, which is not implemented]. Since I need some feedback here, I will present it now. The next step then would be to bring the CONFIG_ADXL345_STREAM implementation based on RTIO up. I have some POC setup here, but it's not as stable. That's why I present still first the older fetch & get update.

Note, I tried to organize the patches/commits a bit into the following order:

  • Initial commits cover formatting, renaming, removal of redundant fields, such kind of refactoring
  • Then follows some cleanupf of structures
  • Clean up of some of the functions
  • Introduction of the updated interrupt handling
  • Introduction of the updated init function
  • Auxiliary functions like FIFO flushing, etc

Please take this commit series as proposal. Each commit is checkpatch'd and verified compiling w/ and w/o TRIGGER config enabled. The final state verified working in all modes (STREAM/RTIO is not worse than before). Working for several weeks on the code easily results in renamings and formatting. To me it makes all sense, let me know if this is acceptable or still needs to be stripped out.

Rubusch added 18 commits April 24, 2025 16:51
Reorganize driver source. Regroup defines and format according to
checkpatch. Remove ';' from macros, in case put parens according to
checkpatch.pl, fix indention and long lines.

This is a preparatory step for upcomming implementation.

Signed-off-by: Lothar Rubusch <[email protected]>
Rename defines to make it more comprehensible. Enhance consistency and
remove duplicates.
Clearly distinguish if using an ADXL345_REG_ i.e. the register, or just
a single bit inside a register.

Apply bitfield macros, such as BIT(), GENMASK(), FIELD_GET(), etc.
to factor out plain logic operations. Help out readability and
maintainability.

This step is a preparation for upcoming implementation on this sensor
driver.

Signed-off-by: Lothar Rubusch <[email protected]>
Rename function and make it more comprehensive and consistent. Since
similar functions are named rather "update bits" e.g. in regmap under
linux. Keeping similar names, might increase readability.

Signed-off-by: Lothar Rubusch <[email protected]>
Remove the function since it is not used.

Signed-off-by: Lothar Rubusch <[email protected]>
Use enum for selected_range as a refactoring.

Signed-off-by: Lothar Rubusch <[email protected]>
Convert the type of is_full_range to a bool, since it is used as bool.

Signed-off-by: Lothar Rubusch <[email protected]>
Rename it to make it more consistent with other Analog accelerometer
drivers in zephyr. Make the type packed, since it is used as bitfield.

Signed-off-by: Lothar Rubusch <[email protected]>
Change type of fifo_samples to unit8_t since the entries counter will
cover in 6 bit, and we will use this counter for fifo lines or sample
number, not for byte size. Thus it fits in 8 bit.

Signed-off-by: Lothar Rubusch <[email protected]>
Simplify function and remove called subfunction to increase readability.

Signed-off-by: Lothar Rubusch <[email protected]>
Simplify decoder implementation to increase readability and
maintainability.

Signed-off-by: Lothar Rubusch <[email protected]>
Bring in configuration of interrupt line. Let the DTS binding allow to
configure INT1 or INT2. All interrupt based sensor events will go over the
configured interrupt line.

Signed-off-by: Lothar Rubusch <[email protected]>
Add INT1 and INT2 as optional interrupt line. When set, the mapping will
go over one of both.

Signed-off-by: Lothar Rubusch <[email protected]>
Update init, reset and prepare the sensor to work with or without the
configured interrupt lines. The sensor defaults to FIFO BYPASS mode,
when TRIGGER is configured and interrupt lines are set up in the DTS,
it will put it into FIFO STREAM mode.

Signed-off-by: Lothar Rubusch <[email protected]>
Update the implementation of fetch and get. Default to FIFO BYPASS mode.
When GPIO lines are defined in the DT and CONFIG_ADXL345_TRIGGER is set,
Analog's FIFO BYPASS mode is configured. In this case up to watermark
samples are stored in the FIFO then a watermark event is triggered. If
samples are not read out, an overrun event can be configured. Aside, also
data ready event can be sent out by the sensor.

Signed-off-by: Lothar Rubusch <[email protected]>
Flush the FIFO by reading out its elements. Where switching FIFO CTL mode
would also remove the FIFO entries, it would leave the status register
with a triggered data ready, watermark and/or overrun bit set. By
datasheet only read out of the fifo will reset those flags again.

Signed-off-by: Lothar Rubusch <[email protected]>
Make the watermark size of the fifo configurable as watermark.

Signed-off-by: Lothar Rubusch <[email protected]>
Let the application API register handlers for data ready, watermark
and overrun. The implementation so far covers the fetch & get approach.

Signed-off-by: Lothar Rubusch <[email protected]>
Refactor the rtio implementation as preparatory step for the read and
decode implementation.

Signed-off-by: Lothar Rubusch <[email protected]>
@Rubusch Rubusch force-pushed the lothar/adxl345-v0.02 branch from d1edd74 to 1a07f14 Compare April 24, 2025 14:57
@Rubusch
Copy link
Author

Rubusch commented May 25, 2025

Hi all. While still waiting on feedback (since March), I noticed other patches to this driver went through. No problem, I can rebase, but...

@ubieda : I noticed, you seem to be (still?) working on this. Are my changes interfering your current work?
Actually, I'd like to bring in implementation, eventually some of the sensor's event handling. For this, I'd prefer to have a cleaned up driver, first. IMHO parts of the driver are still messy (even buggy?). Nevertheless, depending on how active you are here, my changes might probably bother you here. So, I may wait further / we could coordinate a bit / or I can find me another driver to implement. Could you please let me know your plans with this? Also, if possible I'd appreciate your review on my changes, here.
(Since I'm unsure..) If you read this, it would be nice to get a feedback within the next week or so. TIA

@MaureenHelm @yperess @dimitrije-lilic Did I miss something? The pullrequest was initially blocked for several weeks by a change request. Then suddenly the CR disappeared/was closed? and I needed to do rebase for those patches. Still waiting. Will I still get a feedback? Or is this dropped? Actually I thought of the patches just as a first step, followup steps still pending. Shall I open a different pull request? Shall I split somehow? Would be nice to see some feedback here. TIA

@ubieda
Copy link
Member

ubieda commented May 30, 2025

@Rubusch First of all, apologies as I have not been closely following this PR.

Given this driver has changed significantly since Feburary, would you mind test-driving it once again and pointing out what features are not working?

If some of the issues you've found are still valid, I suggest rebasing this PR with thel atest changes.

It seems both Streaming and Trigger mode should be working, as well as polled reads with Read/Decode API. References:

Thanks for your initiative! I'm sure we'll find something to get your first contribution in.

@Rubusch
Copy link
Author

Rubusch commented Jun 1, 2025

@ubieda Great work! I saw the driver made huge progress and the worst bugs seemed to be fixed now. I guess I should have better checked before how active you guys were already working on this. Well, I was just playing with this sensor, so when I saw the driver did not work, just fixed it somehow. At least, I saw some of your fixes were the things I'd also liked to do, so I started on the right track already, yeah!

Further, I learned I should have split up my stuff a bit more. Also, extending this initial 3 patches into almost 20 patches, is probably in github way better a close and a new open. Quite a difference to mailing lists. Interesting. Lessons learned!! ;)

Nevermind. I'll close this MR. Perhaps I'll extract some single topics of this patch set, rebase, and prepare smaller individual patch sets. It's probably easier to discuss / accept / deny small individual patches right away.

Note, skimming over the current state: adxl345_sample_fetch() is now only fetching just a single sample set i.e. x, y and z axis, is that correct? When someone would like to setup a trigger but w/o RTIO, for instance if they want to stay with the (smaller) fetch&get implementation (a realistic scenario?) - Is there another mech now around to read out all FIFO entries? Or, is that left to be in the application code to read the FIFO entries, then call several times fetch, and then get sample data? Overrun? As said already, I'm unsure, since I did not test it on my hardware. Currently looks like it only (burst-)fetches the latest set of x, y and z here, but not all entries. Probably I miss something here, or/and it's not relevant.

Thank you so much to all who were involved and to ubieda for coming back to this and letting me know. No problem!!

@Rubusch Rubusch closed this Jun 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: Sensors Sensors bug The issue is a bug, or the PR is fixing a bug platform: ADI Analog Devices, Inc.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants