Skip to content
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

Initial touch driver #346

Draft
wants to merge 11 commits into
base: master
Choose a base branch
from
Draft

Initial touch driver #346

wants to merge 11 commits into from

Conversation

keirlawson
Copy link

@keirlawson keirlawson commented Nov 28, 2023

Very basic wrapper around small portion of the API surface to start with, keen to get feedback on how to evolve.

Closes #342

src/touch.rs Outdated
Ok(TouchDriver {})
}

pub fn init(&mut self) -> Result<(), EspError> {
Copy link
Collaborator

@Vollbrecht Vollbrecht Nov 28, 2023

Choose a reason for hiding this comment

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

in some drivers there is a compelling reason to split init from the creation of the driver - but is this the case for the touch driver? Same goes for calling the config step separately. I think it would be nicer to just call TouchDriver::new(&some_config)?; and be done with all initial steps. Reducing the api surface the user needs to interact on and less chance to do things out of order.

In othere words combine new / init / config into one pub api call

Copy link
Author

Choose a reason for hiding this comment

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

Yea happy to consolidated new + init + config, should the FSM stuff go in there as well? I'm not sure I quite understand what it does...

Copy link
Collaborator

@Vollbrecht Vollbrecht Nov 28, 2023

Choose a reason for hiding this comment

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

if its a onetime config that is not supposed to be changed after init, i also would combine it

Copy link
Author

Choose a reason for hiding this comment

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

hmmm in the case that the FSM mode is set to software a different start function should be used, not sure I'm understanding it right but seem that the point of this is so you can control when it starts in software, and so maybe it shouldn't be part of new? Or have I misunderstood?

@Vollbrecht
Copy link
Collaborator

Because the touch-driver only works on xtensa based esp you need to gate the complete module against the esp32 / esp32s2 /esp32s3 , otherwise its a build errror for the riscv esp's

src/lib.rs Show resolved Hide resolved
@keirlawson
Copy link
Author

Looks like esp32 has a different touch api from s2/s3, so my inclination is to restrict this PR to the later, wdyt @Vollbrecht ?

@Vollbrecht
Copy link
Collaborator

to my understanding, there is an old touch_api only for the esp32, and a newer one that works on all 3 chips. So you probably only use the newer one that can be used by all chips

@keirlawson
Copy link
Author

to my understanding, there is an old touch_api only for the esp32, and a newer one that works on all 3 chips. So you probably only use the newer one that can be used by all chips

Compile against esp32 seems to be failing as the APIs are different though?

@Vollbrecht
Copy link
Collaborator

you need to use the common header api. here this header definitions is shared across all 3. There might be that there are some specific implementations that are only part of one version for example for the s3 that are not found in the othere. But you can implement the basic common set first for all

@Vollbrecht
Copy link
Collaborator

And if you use something out of a specific driver than you need to make sure to gate it to the specific esp, you can than search in the othere drivers if they have similar functions but just use them slighty different. You could try to unifiy it with one pub api and internally just use conditional compilation to get a similar feature set

@Vollbrecht
Copy link
Collaborator

as long as esp-idf-sys is not release with the touch-driver exposed you also need to use a patch.crates-io inside the Cargo.toml to point to the current esp-idf-sys master version, so CI can build it

@keirlawson
Copy link
Author

Ok, I don't have an esp32 so wont be able to test any branches that are for that chip only so my concern is I'll basically be guessing as to what the right logic is in that case

src/touch.rs Outdated

pub struct TouchConfig {
fsm_mode: FsmMode,
configured_pads: Vec<TouchPad>,
Copy link
Author

Choose a reason for hiding this comment

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

This Vec seems to be causing build issues, not sure how best to resolve?

Copy link
Collaborator

@Vollbrecht Vollbrecht Nov 28, 2023

Choose a reason for hiding this comment

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

why do you start collecting all the pads in one struct anyway. In the end from a design perspective it will be problematic, for example if you want to set or read a pin, or if you want to create an ISR/callback for it, you somehow need to be able to address that pin. So a general approach would be here similar to the PinDriver - where each PinDriver is one instance tight to one gpio pin.

If you have problems that some part of the api should only be called once like some of the init code we maybe need to split them of ( need to find that out) - in that case we would have something like a TouchDriver that would do the innit and config stuff - and then something like a TouchPadDriver for each individual pad to get to the individual get / set methods etc. Otherwise if thats not a problem just go with one struct.

Copy link
Author

Choose a reason for hiding this comment

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

So init is universal so I think we will need both, how do you envisage TouchDriver and TouchPadDriver interacting? Create the latter from a method on the former? The FSM stuff is also universal and I'm not sure if that needs to be called after conflagration of individual pads?

Copy link
Collaborator

Choose a reason for hiding this comment

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

one thing we care about is cleaning up behind ourself automatically. So if a PadDriver goes out of scope it needs to be dropped correctly. We could make it that a TouchPadDriver gets a &TouchDriver and so it gets the lifetime of it intrinsically. Also you need to make sure to implement Drop correctly on both, so if TouchDriver gets out of scope the driver gets de-init correctly in reverse order.

Copy link
Author

Choose a reason for hiding this comment

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

Still not totally clear on what's needed here, is there analogous code in some other driver I could look at for inspiration?

Copy link
Collaborator

Choose a reason for hiding this comment

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

For example in the SpiDriver - you can have one spi setup that service multiple connected spi-devices with for example different chip-select lines. So you are creating one overall SpiDriver and for each device you want to use it for you create an SpiDeviceDriver from a concept it would here be similar, though notice because that we have a lot of cases in spi the driver itself is somewhat complicated, so you dont need to try to understand how it works there - just how the concept works.

Copy link
Author

Choose a reason for hiding this comment

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

Ok, updated to mimic the approach of SpiDriver, lmk what you think

@Vollbrecht
Copy link
Collaborator

Ok, I don't have an esp32 so wont be able to test any branches that are for that chip only so my concern is I'll basically be guessing as to what the right logic is in that case

just go with the common api for now that is shared between all and you should be good. After that you can try to play with the specific stuff

@Vollbrecht
Copy link
Collaborator

don't forget to run cargo clippy and cargo fmt the same way you run cargo build and fix all the mentioned problems

src/touch.rs Outdated Show resolved Hide resolved
src/touch.rs Outdated Show resolved Hide resolved
@keirlawson keirlawson requested a review from Vollbrecht December 4, 2023 10:57
Copy link
Collaborator

@Vollbrecht Vollbrecht left a comment

Choose a reason for hiding this comment

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

Do you see the clippy warning in the CI for the normal esp32. The return type of the implementation on esp32 is different. You need to handle this case with a conditional compilation.
Since the touch module itself is already scoped to esp32 -esp32s3 i think the #[cfg(any(esp32, esp32s2, esp32s3))] on each codeblock could be removed since the compiler should not look here in other cases.

@keirlawson
Copy link
Author

I've disabled for esp32 as I dont have the ability to test against that, so figured keeping things simpler will be easier for me as I'm new to all this

@keirlawson keirlawson requested a review from Vollbrecht December 4, 2023 16:34

impl TouchPadDriver<TouchDriver> {
pub fn new_single_started(pad: TouchPad, config: TouchConfig) -> Result<Self, EspError> {
let mut touch = TouchDriver::new(config)?;
Copy link
Collaborator

@Vollbrecht Vollbrecht Dec 4, 2023

Choose a reason for hiding this comment

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

crating the TouchDriver inside the TouchPadDriver makes little sense, ( Sorry i hope i am not rude here ;D ) You can explain your thinking here.

My thinking: As in this case you wouldn't even need all the TouchDriver buisness in the first place. Its fine to create two different version of TouchPadDriver, one with new() and one with new_single(). Where the first one takes a reference to the TouchDriver that is created before so multiple TouchPadDrivers can be created, and in the later case it takes an owned value of TouchDriver, where one would only ever use on pin.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

ESP32/S2/S3 touch sensor support
2 participants