Skip to content

Conversation

@davidv1992
Copy link
Contributor

Main motivators are:

  • More consistent interface that is better misuse resistant.
  • Easier to extend with support for Automatic Ack/Nack of addresses in async variant.
  • Better support for cancelation and capable of better surfacing what the hardware can actually do.

The code changes also fixes some issues in 10-bit addressing. It should now match the behaviour specified in UM10204

@davidv1992
Copy link
Contributor Author

This is only the rewrite of the blocking interface. If this design is considered reasonable I can extend it to the async side and actually do the support around automatic address ack/nack. The choice for separate types for the blocking and async slave interfaces is that both will need different code to run on drop, which cannot be done another way because of restrictions on Drop implementations.

Copy link

@tdittr tdittr left a comment

Choose a reason for hiding this comment

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

A few thoughts for now, going to finish the review next week.

Copy link

Choose a reason for hiding this comment

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

In general I think we should improve the granularity of the returned errors to make debugging easier.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

All these errors are essentially identical (bus is in a strange state), so there isn't really anything to separate them.

Copy link

@tdittr tdittr left a comment

Choose a reason for hiding this comment

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

I like the new API, however it does feel a bit rough around the edges.

Should we maybe implement the async version and improve the documentation before merging?

i2c.stat().write(|w| w.slvdesel().deselected());
return Ok(Response::Complete(xfer_count));
// inhibit drop
core::mem::forget(self);
Copy link

Choose a reason for hiding this comment

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

Nit-pick: I would replace with a destructuring assignment.

Suggested change
core::mem::forget(self);
let BlockingI2cSlaveWrite{..} = self;

Or alternatively have a Self::defuse method.

Copy link

Choose a reason for hiding this comment

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

I like this example for showing a real-world use-case 👍

Copy link
Contributor

@jerrysxie jerrysxie left a comment

Choose a reason for hiding this comment

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

@davidv1992 Still going through the review, just one question about the overall goals and next steps:

  1. For all the ODP I2C slave HALs, the plan is to have a HW agnostic traits interface to be implemented by both embassy-imxrt and embassy-npcx, is this a step toward that direction? The I2C traits are eventually to be upstreamed to embedded-hal, but meanwhile we should probably have it as a independent crate in ODP until the upstreaming can happen.
  2. We do have some clients that relies on this i2c slave interface already. Merging this will require a bit coordination.

@jerrysxie jerrysxie requested a review from Copilot April 14, 2025 23:13
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.

@davidv1992
Copy link
Contributor Author

@jerrysxie Yes, this is aimed to be a step in that direction. The exact shape of a hardware agnostic trait is still in the design phase, but something along these lines is what we are trending towards. The main pain points right now (though those are less relevant for the two crates you mention) is that some hardware has quite limited i2c slave support.

As for this requiring some coordination to merge, that is not entirely unexpected. My main goal at this stage is to gather feedback on the overall shape of the design in preparation for doing the same reworking of the interface in the async case. So far, reactions seem positive, but if on your end you feel different about it it would be nice to catch that before I have sunk a bunch of work into the async version, as it's likely going to be somewhat more complicated to implement.

@davidv1992 davidv1992 marked this pull request as draft April 24, 2025 09:25
@davidv1992 davidv1992 force-pushed the i2c-new-interface branch 4 times, most recently from 2f7a2e6 to 77854a9 Compare April 24, 2025 12:25
@jerrysxie
Copy link
Contributor

@jerrysxie Yes, this is aimed to be a step in that direction. The exact shape of a hardware agnostic trait is still in the design phase, but something along these lines is what we are trending towards. The main pain points right now (though those are less relevant for the two crates you mention) is that some hardware has quite limited i2c slave support.

As for this requiring some coordination to merge, that is not entirely unexpected. My main goal at this stage is to gather feedback on the overall shape of the design in preparation for doing the same reworking of the interface in the async case. So far, reactions seem positive, but if on your end you feel different about it it would be nice to catch that before I have sunk a bunch of work into the async version, as it's likely going to be somewhat more complicated to implement.

Hi, @davidv1992! One more question regarding the plan to add support for Automatic Ack/Nack of addresses in async variant. I tried this but the code becomes really messy, because the NXP auto-ack combined with DMA requires the code to set up DMA ahead of time. For auto-ack of a write, we have to set up DMA for write and have DMA ready to go before listening. If it is a write, everything proceeds as expected. But it is a read, then we have to abort the write DMA and manually ack the address and set up read DMA again. It made the code super messy. How do we plan to deal with that?
image

@davidv1992 davidv1992 force-pushed the i2c-new-interface branch 2 times, most recently from 67618e8 to d240c12 Compare April 25, 2025 14:13
@akshat2112 akshat2112 self-requested a review April 30, 2025 23:48
@davidv1992
Copy link
Contributor Author

davidv1992 commented May 7, 2025

Hi, @davidv1992! One more question regarding the plan to add support for Automatic Ack/Nack of addresses in async variant. I tried this but the code becomes really messy, because the NXP auto-ack combined with DMA requires the code to set up DMA ahead of time. For auto-ack of a write, we have to set up DMA for write and have DMA ready to go before listening. If it is a write, everything proceeds as expected. But it is a read, then we have to abort the write DMA and manually ack the address and set up read DMA again. It made the code super messy. How do we plan to deal with that? image

@jerrysxie Sorry for the late response, missed this before my vacation. Yes there is some mess here, and there is a lot of complications due to potential race conditions between the software and the hardware, but the way I manage it currently is by having the rest of the code more streamlined so that the expectation doesn't match scenario becomes less of an alternate path. I am still in the process of cleaning up the code, but everything is implemented right now.

@davidv1992 davidv1992 force-pushed the i2c-new-interface branch from 044a9e0 to c351e90 Compare May 7, 2025 07:58
@davidv1992 davidv1992 marked this pull request as ready for review May 7, 2025 07:58
@davidv1992 davidv1992 force-pushed the i2c-new-interface branch from f08aef0 to e84bb4f Compare May 8, 2025 08:12
@github-actions
Copy link

github-actions bot commented May 8, 2025

Cargo Vet Audit Passed

cargo vet has passed in this PR. No new unvetted dependencies were found.

@github-actions github-actions bot added the cargo vet PR requiring auditor review label May 8, 2025
@davidv1992 davidv1992 requested review from jerrysxie and tdittr May 8, 2025 08:14
@davidv1992
Copy link
Contributor Author

@jerrysxie the CI fails, but this seems to be an issue with the setup of the pipeline, not the code. Would it be possible for you to look into this?

@davidv1992 davidv1992 force-pushed the i2c-new-interface branch from f404fa7 to bc756a7 Compare May 9, 2025 09:53
@jeffglaum jeffglaum moved this to In review in Embedded Controller May 12, 2025
@jeffglaum
Copy link
Contributor

@JamesHuard , @felipebalbi , @RobertZ2011 can you guys please review and provide feedback? Thanks.

Main motivators are:
 - More consistent interface that is better misuse resistant.
 - Easier to extend with support for Automatic Ack/Nack of addresses
   in async variant.
 - Better support for cancelation and capable of better surfacing what
   the hardware can actually do.

The code changes also fixes some issues in 10-bit addressing. It should
now match the behaviour specified in UM10204
This is done through the expect_read and expect_write interfaces, as
automatic acknowledgement requires the dma to be in place beforehand.
This register contains both write-to-trigger bits and bits that represent
semi-permanent state. This commit ensures we don't accidentaly write 1s
to the write-to-trigger bits, as the hardware doesn't clear these
automatically.
@davidv1992
Copy link
Contributor Author

@jeffglaum You have assigned this one back to me, but it is unclear what is required from me at this point. Could you clarify that?

Copy link
Contributor

@felipebalbi felipebalbi left a comment

Choose a reason for hiding this comment

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

I didn't attempt to run the examples yet, but the code looks easy enough to read. Since you're using auto-ack, did you manage to quantify any changes to bus utilization?

}
}

impl<'a> I2cSlave<'a, Blocking> {
Copy link
Contributor

Choose a reason for hiding this comment

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

Just curious: why remove the Mode type parameter here?

@jeffglaum
Copy link
Contributor

@jeffglaum You have assigned this one back to me, but it is unclear what is required from me at this point. Could you clarify that?

Just assigning to you, to complete the PR (looks like there are still open discussion points which are blocking the merge). Thanks.

@jeffglaum
Copy link
Contributor

@davidv1992 are you intending to complete this PR (looks like it had approvals) or to abandon? Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cargo vet PR requiring auditor review

Projects

Status: In review

Development

Successfully merging this pull request may close these issues.

6 participants