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

Add a tx only and a rx only serial instance #34

Merged
merged 5 commits into from
Jan 11, 2019

Conversation

david-sawatzke
Copy link
Member

@david-sawatzke david-sawatzke commented Jan 5, 2019

This also makes the serial stuff in #27 obsolete.
Additionally by virtue of how it works also implements stm32-rs/stm32f4xx-hal#49 here.

Not sure how we should handle the release method. It currently works but you get a () for the unused pin back.

Currently untested

@david-sawatzke david-sawatzke force-pushed the serial_mult branch 3 times, most recently from e5ca471 to bd3478f Compare January 5, 2019 22:14
@HarkonenBade
Copy link
Member

I have some thoughts on this, will put together an actual review in a bit, kinda busy atm

src/serial.rs Outdated Show resolved Hide resolved
let rxpin = ();
let mut serial = Serial { usart, pins: (txpin, rxpin) };
serial.enable(baud_rate, clocks);
serial
Copy link
Member

Choose a reason for hiding this comment

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

Why not have the Tx only constructor just return a Tx<USART>?

Copy link
Member Author

Choose a reason for hiding this comment

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

I want to enable listen and potential future things for Rx/Tx only usarts. Returning a Tx would also make release pretty hard to do.

Copy link
Member

Choose a reason for hiding this comment

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

To be fair currently if you split() an interface you already lose the ability to release, so maybe Tx and Rx need to keep hold of their pins and implement release each. Also I could see claim for being able to call listen/unlisten on Tx and Rx instances, or even just make the listening methods on some global type, given they are atomic and not bound to a given object.

Copy link
Member Author

Choose a reason for hiding this comment

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

That's why stm32-rs/stm32f4xx-hal#49 was done. As a side effect, this is also accomplished by this pull request (an separate object sounds really annoying)

Copy link
Member

Choose a reason for hiding this comment

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

I don't see how that fixes split usarts from being unable to release their pins?

Copy link
Member

Choose a reason for hiding this comment

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

I suppose I tend to see splitting usarts as a useful and important feature as it allows them to be partially shared into interrupt handlers in a sensible way without lock contention.

Copy link
Member

Choose a reason for hiding this comment

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

@HarkonenBade I'm not quite sure about the usefulness of splitting, to me that is mostly a historical thing rather than a practicality. It would make most sense if Rx and Tx were mostly used independently but I really haven't seen that being used anywhere in the wild. In fact I often have to share Rx/Tx together with my interrupt handlers to make use of them (unless I only need one of them).

Maybe it would make sense to actually implement the serial traits directly on the serial port handle to allow direct use of a bi- or unidirectional serial channel with release capability but also keep the possibility to split in case a serial port is meant to be used in two separate places. What do you think?

Copy link
Member

Choose a reason for hiding this comment

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

That sounds reasonable to me, also I'm unsure over the use of generating temporary Tx/Rx instances to impl the Read/Write traits, it would seem more appropriate to move the implementations out to free functions that take a *const USART argument.

Copy link
Member Author

Choose a reason for hiding this comment

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

Moved it out in separate functions with RegisterBlock, I could remove the USART parameter from Tx & Rx type, not sure if I should.

Copy link
Member

Choose a reason for hiding this comment

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

I'd leave it there, its potentially relevant to distinguish Tx and Rx objects from different USART types.

let txpin = ();
let mut serial = Serial { usart, pins: (txpin, rxpin) };
serial.enable(baud_rate, clocks);
serial
Copy link
Member

Choose a reason for hiding this comment

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

As above but for Rx

Copy link
Member

@HarkonenBade HarkonenBade left a comment

Choose a reason for hiding this comment

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

I think there are a few bits that might need thinking about further.

Copy link
Member

@HarkonenBade HarkonenBade left a comment

Choose a reason for hiding this comment

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

I've taken another look over and everything LGTM 👍

src/serial.rs Outdated
}
}

/// Tries to write a byte to the uart
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
/// Tries to write a byte to the uart
/// Tries to write a byte to the UART

src/serial.rs Outdated
}
}

/// Tries to read a byte from the uart
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
/// Tries to read a byte from the uart
/// Tries to read a byte from the UART

Copy link
Member

@therealprof therealprof left a comment

Choose a reason for hiding this comment

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

Would be great if we could get a doc example for unidirectional use. Otherwise LGTM.

@HarkonenBade
Copy link
Member

Actually, would it also be worth updating at least one of the examples that doesn't really need split under this? Maybe the plain echo?

@therealprof
Copy link
Member

Actually, would it also be worth updating at least one of the examples that doesn't really need split under this? Maybe the plain echo?

I haven't looked in detail but is this even a possibility, i.e. does the implementation allow for multiple independent uses of the chosen USART to attach multiple independent pins to it? If so that might be construed by some as unsafeness... 😏

Anyway, I'd be okay with modifying the examples or adding another, like a plain hello world, but I strongly favour better documentation over examples.

@HarkonenBade
Copy link
Member

@therealprof It doesn't let you define multiple usarts with the same pins, but the way the impls of read and write for usarts are worded also implements them for duplex usarts. So a full duplex usart can have both read and write called on it, and thus doesn't require splits if you don't need to send the parts to different places.

@therealprof
Copy link
Member

@HarkonenBade Sorry, I misunderstood you then. Sure, go ahead.

@HarkonenBade
Copy link
Member

HarkonenBade commented Jan 11, 2019

Though this has raised an interesting question for me, could we shift it so that split() returns (Serial<USART1, TxPin, ()>, Serial<USART1, (), RxPin>) and just eliminate Tx and Rx all together?

It would mean that we would need to be more careful in future if we offer any ability to re-configure the peripheral at runtime.

@david-sawatzke
Copy link
Member Author

I think this would make a destructor pretty hard. It also has issues with the listen/unlisten calls (the classic race condition thing). I also don't like two serials of the same port existing, for me it looks like a hack (because it is).

@HarkonenBade
Copy link
Member

That's fair, it was just a thought based on the pleasing way the read/write impls turned out.

Also add the `Write` implementation for Serial
Copy link
Member

@therealprof therealprof left a comment

Choose a reason for hiding this comment

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

LGTM, thanks!

@therealprof therealprof merged commit 0ffbce7 into stm32-rs:master Jan 11, 2019
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.

3 participants