Skip to content

Conversation

jobitjoseph
Copy link

@jobitjoseph jobitjoseph commented Sep 8, 2025

Problem
The current HardwareSerial implementation has Serial.available() hardcoded to return -1, making it impossible to use standard Arduino serial patterns like echo loops or data polling. This affects all CH32 series MCUs (CH32V003, CH32V203, CH32X035, CH32V103, CH32V307).
Root Cause

available() function returns -1 instead of the actual byte count
No RX buffering implementation
No interrupt-driven reception

Solution
This PR implements proper UART RX buffering with interrupt handlers for all CH32 series MCUs while maintaining backwards compatibility with other Arduino cores.
Changes Made

Added conditional RX buffering - Only enabled for CH32 series MCUs
Implemented interrupt handlers - For all UART variants (USART1-8, UART4-8)
Fixed core functions:

available() - Returns actual buffered byte count
peek() - Returns next byte without consuming it
read() - Reads from interrupt-filled buffer

Maintained compatibility - Non-CH32 MCUs use original behaviour
Safe implementation - Only creates handlers for existing Serial objects

Technical Details

64-byte RX buffer per UART with overflow protection
Conditional compilation prevents linker errors
Interrupt priority set to 2 for all UARTs
Buffer variables are only allocated on CH32 MCUs

Testing

Verified on CH32X035 board
Serial.available() now returns 0 when no data (instead of -1)
Echo functionality works correctly
No compilation errors on any supported MCU

Backward Compatibility

Zero impact on existing projects
Non-CH32 Arduino cores unchanged
Existing CH32 code works without modification

Before:
Serial.available(); // Always returned -1
After:
Serial.available(); // Returns actual byte count (0, 1, 2, etc.)

Tested on CH32X035

@maxint-rd
Copy link
Contributor

Hello @jobitjoseph , thank you for your contribution.
PR #201 (replacement of PR #145) also addresses this issue. Did you have a look at that PR? It also includes the changes of PR #180.
Due to limited hardware available for testing it only implements USART1 and USART2. It does support simultaneous use of two USART instances.

A quick look at your changes shows that they implement interrupt handlers for up to 8 usart instances. At the moment I don't have time for a full look at the code. Can you tell what the other differences offer? Do you have hardware to support up to 8 usart instances?

Perhaps we can see if these two PRs can be merged into one that replaces PR #201.
Eventually it's probably best if other CH32 users only have to merge one PR for improved serial usage.

@jobitjoseph
Copy link
Author

jobitjoseph commented Sep 8, 2025

#145

Hi,
Just looked at PR #201 and you're right, it solves the main problem. Mine extends it to more UART instances when needed. Currently, I only have CH32V003 and CH32X035(4 USART) variants in hand to test.
Makes sense to combine them rather than having duplicate solutions.

@maxint-rd
Copy link
Contributor

Okay, I only had V003/V002/V006/X033 (TSSOP20) for testing. The TSSOP20 package of the X033 doesn't have all serials fully available, so I didn't implement more than two.

I added some defines in a header file to allow selection of either one instance of those two, or using two instances simultaneously. If I remember well, the changes of PR #180 were also required for that, so I included those in #201.

Whenever I have a bit more time to look into it, I will look again at your changes.

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.

2 participants