-
-
Notifications
You must be signed in to change notification settings - Fork 79
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
Modify UART Class to Make Use of the txBuffer #304
base: main
Are you sure you want to change the base?
Conversation
I pushed another commit that adds the I also noticed that the original commit on this PR also fixes |
I have tried this change because it makes complete sense and also because I am having issues with the Sparkfun RA6M5 Serial1 port. I have copied the changes as indicated and I had issue :
It then compiled and worked without a problem. FYI The problem was not solved on the RA6M5 with this change..the first character received is somehow 0x0 instead of the expected 0x7E. It is sent by the device as monitored and detected with an external tracer (Saleae). Also the sketch does work unmodified with a UNOR4 Wifi. Different issue |
txc is defined as a member variable of the UART class. I did this because a global would be shared between instances and I didn't want to introduce issues if two UARTs were working at the same time. There is another txc defined in the interrupt callback as a local variable, but it is only used in the context of the handler. That's because the handler doesn't belong to any one instance. |
Thanks. My error as I missed copying the txc definition from the header file. |
cores/arduino/Serial.cpp
Outdated
uart_ptr->tx_done = true; | ||
if(uart_ptr->txBuffer.available()){ | ||
static char txc; | ||
txc = uart_ptr->txBuffer.read_char(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it OK to use a static variable here instead of uart_ptr->txc? Would this work correctly if there are multiple uarts working simultaneously?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a good question. I made it static because it was being passed as a pointer on the next line but I didn't really think about it being there in multiple instances.
I think that it will be OK because R_SCI_UART_Write is going to use that data one line later and then we're done with it. I think it would be OK to make it not static.
I wish I could grab a whole chunk of the tx_buffer there so the code in r_sci_uart.c could make effective use of the FIFO. The problem is that I would need to know where the data in the tx_buffer wraps around or I could run off the end.
I have a separate branch that uses DMA and it doesn't have this problem because I set the DMA extended repeat area to match the tx_buffer and the DMA controller will automatically wrap back around. But that code seems to be broken in other places.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, looking at it now, I don't see why I don't just use uart_ptr->txc
instead. Maybe I thought because it was an interrupt handler that I wouldn't have access but I do.
I'll update the branch tonight and retest a little.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I updated the code to use the member variable instead. It tests ok. I did a lot of printing without any failures. Unfortunately I seem to have messed up my branch.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated once more to load characters 16 at a time in the interrupt callback. This takes advantage of the FIFO to reduce the number of interrupts.
OMG! What did I do wrong? Where did all those other commits come from? What do I do? @per1234 can you help? |
Hi @delta-G. Start by doing a hard reset of the branch back to the last commit (9b439c5) before the unwanted commits were introduced:
Now all the unwanted commits have been removed from the branch, but the recent commit you want (2832d3d) was also removed. So you need to cherry-pick that one back onto the branch:
Now you need to force push the branch to your fork on GitHub:
⚠ You should never do a force push to a production branch in a repository since this will cause the branch's history to be different from that in clones of the repository, which will be a bad time for project collaborators. However, it is fine to do so in branches that are being used to stage commits as is the case with a PR branch. GitHub will even automatically add a helpful note to the pull request thread to make it clear what happened. If you want to bring your branch up to date with the
Then force push the updated branch to your fork on GitHub:
|
Thank you @per1234 for the detailed instructions. You even had the hashes in there for me so I didn't have to look in two places. Nobody does it like you do. |
Here's some test code for a WiFi that just print alternating lines of Lewis Carroll to both Serial and Serial1. It performs as expected. I also ran a test where I was echoing Serial to Serial1 and vice versa and it worked fine for that.
|
I added one more commit. I moved a few things around in |
Hi, is there an ETA of when this PR will be merged and published? |
I opened this to replace #303 because it had a bunch of files included from submodules. This should be cleaner. Sorry for the mess.
This pull request makes changes in Serial.h and Serial.cpp so that the UART class will make use of the TxBuffer. This greatly reduces the amount of time that Serial.print will block, especially for long strings. Currently the class makes no use of the 512 bytes it has reserved for a txBuffer.
I've changed the write functions so that they will load characters into the buffer and start a transmission if one is not already going.
Because the HAL takes a pointer to the data, I added a char variable to read into so the buffer can be advanced. I cannot attempt to send a larger portion of the buffer because the HAL expects contiguous memory and it will break in the case where the string to send rolls over the end of the ring buffer. I will submit another PR later to deal with that if I find a good way.
While it is possible to submit an entire string to the HAL at once, the string is submitted by pointer so it creates a possible race if there is some other code that changes the string before it gets fully printed. By utilizing the txBuffer, this problem is also alleviated.
I have tested this code in several configurations and it appears to work just dandy. Please let me know what you think.