Skip to content

Can Be Closed in favor of #6272 -- HardwareSerial: make begin() virtual #6176

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

Closed

Conversation

sgalabov
Copy link

Make HardwareSerial's begin() method virtual, so that subclasses are able to override it where needed.
This is useful for example when we want to re-use the same uart with different RX/TX pin pairs for different tasks.

@me-no-dev
Copy link
Member

This is useful for example when we want to re-use the same uart with different RX/TX pin pairs for different tasks.

How does this work exactly? Same UART, but different Pins in different tasks?

@sgalabov
Copy link
Author

This is useful for example when we want to re-use the same uart with different RX/TX pin pairs for different tasks.

How does this work exactly? Same UART, but different Pins in different tasks?

Yes, for example I have a project where I need to initially program a small ATTiny MCU on the same board via UPDI (using UART), but then I do not need to use it again, whereas I can use the UART, especially in ESP32-S2/ESP32-C3 cases for different purposes.

@me-no-dev
Copy link
Member

But what is preventing you now? Just reinit with new pins once done with the ATTiny?

@me-no-dev
Copy link
Member

cc @SuGlider

@sgalabov
Copy link
Author

But what is preventing you now? Just reinit with new pins once done with the ATTiny?

Currently we can do that via Serial.begin() by passing the new pins and all would be well if no-one after that would happen to call begin() again while we're doing what we need to do...

In a lot of cases, however, (UPDI programming library comes to mind), the libraries in use would simply do Serial.begin() multiple times. The current implementation of HardwareSerial does not like that - it falls back to the default pins for the given UART and things break miserably... :-) since I can imagine other people relying on this functionality and I wouldn't want to mess with it, I would simply prefer to be able to subclass HardwareSerial and implement the handling of persistent different pins there.

If the above wasn't clear enough:
void begin(unsigned long baud, uint32_t config=SERIAL_8N1, int8_t rxPin=-1, int8_t txPin=-1, bool invert=false, unsigned long timeout_ms = 20000UL, uint8_t rxfifo_full_thrhd = 112);

If I call Serial.begin(115200, SERIAL_8N1, x, y) for example - everything will be fine and Serial will start working on rxPin x and txPin y. Unfortunately this will be true only until someone (e.g., in a library) needs to switch, say, the baud rate and does:
Serial.begin(9600)
This will break the UART in question as it will fall back to its default pins, depending on either pins_arduino.h (if they're defined there) or as defined in HardwareSerial.cpp..

@me-no-dev
Copy link
Member

@SuGlider wasn't this fixed? There should be a way to do this without resorting to new classes and implementations. We already have this in Wire for that exact reason.

@sgalabov I think we should actually make Serial not reassign pins if they are not specifically set. Serial.setPins() should actually be used to fix the pins (and change them later on).

@sgalabov
Copy link
Author

@SuGlider wasn't this fixed? There should be a way to do this without resorting to new classes and implementations. We already have this in Wire for that exact reason.

@sgalabov I think we should actually make Serial not reassign pins if they are not specifically set. Serial.setPins() should actually be used to fix the pins (and change them later on).

@me-no-dev, something like the last commit? :-)

if(_uart_nr == 1 && rxPin < 0 && txPin < 0) {
rxPin = RX1;
txPin = TX1;
if(_uart_nr == 1) {
Copy link
Member

Choose a reason for hiding this comment

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

those do the same exact thing as before :) reassign the pins if they are not -1

Copy link
Author

Choose a reason for hiding this comment

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

Nope, they assign to the _rxPin and _txPin, which are now protected members of the class, so they persist.
They are now only changed in begin() if:

  • rxPin parameter is > -1 -> we take its value as the _rxPin value
  • txPin parameter is > -1 -> we take its value as the _txPin value

Then later, if any of the _rxPin/_txPin is still -1 we take the defaults.

This allows us to only override the already assigned pins where actually needed I believe..

@SuGlider
Copy link
Collaborator

@sgalabov @me-no-dev
I think that this PR is a good idea. Let me review it along with RTS/CTS pins and hardware flow control functionality.
I'll submit a separated new PR that includes @sgalabov's changes and #6185 in a single one.

Does it sound good for you guys?

@sgalabov
Copy link
Author

@sgalabov @me-no-dev I think that this PR is a good idea. Let me review it along with RTS/CTS pins and hardware flow control functionality. I'll submit a separated new PR that includes @sgalabov's changes and #6185 in a single one.

Does it sound good for you guys?

Fine with me, thanks. :-)

@me-no-dev
Copy link
Member

@SuGlider I could have sworn that we discussed this and it has been already implemented :D
Sounds good to me

@VojtechBartoska VojtechBartoska added the Area: Peripherals API Relates to peripheral's APIs. label Feb 2, 2022
Copy link
Collaborator

@mrengineer7777 mrengineer7777 left a comment

Choose a reason for hiding this comment

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

Keeping a protected copy of the RX, TX pins is the right way to do this. The code is clean and consistent. The protected variables are used in all the correct places instead of the original parameters. Braces are consistent. Nice work!

@SuGlider
Copy link
Collaborator

This PR will be replaced by #6272

Copy link
Collaborator

@SuGlider SuGlider left a comment

Choose a reason for hiding this comment

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

To be replaced by #6272

@SuGlider SuGlider added the Resolution: Expired More info wasn't provided label Feb 14, 2022
@SuGlider SuGlider changed the title HardwareSerial: make begin() virtual Can Be Closed in favor of #6272 -- HardwareSerial: make begin() virtual Feb 14, 2022
@VojtechBartoska VojtechBartoska removed this from the 2.0.3 milestone Feb 15, 2022
@me-no-dev me-no-dev closed this Feb 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: Peripherals API Relates to peripheral's APIs. Resolution: Expired More info wasn't provided
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants