-
-
Notifications
You must be signed in to change notification settings - Fork 19.3k
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
Templatized serial classes #11982
Templatized serial classes #11982
Conversation
In spite of working for you, the changes weren't passing Travis CI. One issue was that you can't use The other issue is that the unsigned char buffer[RX_SIZE]; // <--- is RX_SIZE picked up as 0 here? Does the My temporary workaround was just to drop the |
I've also just added a commit to make the code more readable (and maintainable) by defining macros for the long template signatures. So in future they will only need to be changed in one place instead of several. |
Is it possible to define a struct and pass that as template parameter?
Additionally, one could use a typedef by "using" to simplify these things:
Finally, I do not like these specializations
All the values can be directly calculated by the template parameter.. I like templates, but I still have the impression that these commits make the code longer and more complicated. Therefore, I would suggest to simplify it a bit more. |
Well, the main problem seems to be that when using TX_SIZE = 0 (the default Marlin configuration), the structure gets defined as struct ring_buffer_t {
unsigned char buffer[0];
volatile uint8_t head, tail;
}; And then the initializer does not work, as it is { { 0 }, 0, 0 } And that would assign a 0 to an empty array. According to c/c++ standard, if i initialize any member, then all the other missing members of a struct will be implicitly initialized to 0. Maybe the best approach would be to reorder those structs: struct ring_buffer_t {
volatile uint8_t head, tail;
unsigned char buffer[TX_SIZE];
}; and then initialize them by { 0 } As the struct is declared inside the template, it does require most of that |
I do agree with this. I wasn´t sure if it would be acceptable to do it. That is why i didn´t 👍 |
@dgrat : I haven´t tried the idea of passing an struct as template parameter. But a configuration type could work, you are right. Maybe that could be a better practice here... |
The idea of those specializations is to reuse the CMSIS defined symbols, instead of hardcoding those values. The main problem is that i wanted constexprs (otherwise, SRAM is wasted to store non-changing values!! and code size increases) I always felt that the |
@thinkyhead , @dgrat ... Changed to a struct as template parameter to configure the class... |
@thinkyhead : Unfortunately, But, do not worry about how much space the We only use the type, but never instantiate it... advantages of the On the MarlinSerial class, the type changes based on the maximum size of the buffer: > 256 will use a uint16_t, less than that will use a uint8_t |
In that case, reverted! |
So… How far does this go to eliminating the need for From here it would be good to have some documentation on how Marlin handles serial I/O and how to set up new serial devices to use the best available option. |
@thinkyhead : BTW: This PR objective was to allow more than 1 |
Anything left to do here before we release this into the wild? |
@thinkyhead : Basically it is working... As said before, just waiting for feedback on code styling ;) |
I am looking to enable a Creatbot Touch Panel (same as Wanhao and MonoPrice screen) that is connected to pins 15 RX3 & 14 TX3. How do I configure or define software serial pins for a 2560? |
If that panel emits standard Gcode to control Marlin, you just need to #define SERIAL_PORT_2 3 |
That is the "assumption". I tried 3 and no luck. Just to confirm: Where are the software serial port pins defined? In the boards pins file? |
There is no such definition. The serial port pins are fixed by the Atmega2560 processor. They can´t be moved or remapped to other pins! |
Thanks, will run pins_debug to be sure. Could also be that screen looks for a response and is not getting the right one so refuses to start. I did try different baud rates but originally was 250000. |
I enabled PINS_DEBUGGING, commented out serial port 2, and did M43. As hoped and expected I got this:
I then uncommented serial port_2 3, did an M43 and got this:
So pins still not assigned. Seems like the pins are not defined somewhere or that 3 is the wrong port. Any ideas? |
The pins are not reflected as assigned. That is good news. The only pins that will reflect as assigned are IO pins, but UART are not... as they are being used for UART, not for general purpose IO |
So you are saying that they are actually assigned even though they are not showing up as such? When using TMC software serial you need to define them in the boards file, why would you not do the same here? We are talking about software serial right? |
No, this is hardware serial. |
Ok let me start from the beginning. I am trying to use a touch panel that uses g-code (works in a manufacturers custom version of marlin). It is connected to pins 14 and 15. Should I be using hardware serial or software serial? If so, do I need to assign those pins anywhere? |
If it is connected to pins 14 and 15 of the atmega processor, according to its datasheet, there is no hardware UART there. Pin 14 says (XCK2/PH2), and Pin 15 says (OC4A/PH3). |
Yes! Now I know where to start. I know people don't like it but it is being used for TMC control. Can you point me in the right direction? Where do I define the software serial pins? What is the define syntax? There is an incredible lack of documentation on this. A few people got it working but are never clear as to how. Sorry to sound like a tiresome idiot that I am. I have been working on this for 3 weeks and need only this and the power button to finish. |
There is a hardware serial! Most common error with serials is connecting RX to RX and TX to TX instead of crossing them RX to TX and TX to RX. |
According to Arduino those pins are hardware serial on the 2560, https://www.arduino.cc/reference/en/language/functions/communication/serial/ (as previously stated by AnHardt ^^) |
Ok I am getting whiplash. So hardware serial it is? If understand correctly, it is baked in so all I need is:
Any other considerations? Thank you everyone! |
That should be all that is needed. |
Am I correct in thinking that this implementation pushes everything into standard isr, so it is really just for reading gcode from another device? To do general serial communication with another MCU for other purposes you are pretty much limited to HardwareSerial? |
You are wrong. This Serial class can be used for any purpose besides reading gcode. |
Cool. This is referenced with MYSERIAL1 for general purpose io after it has been defined? |
No, it depends. If you define SERIAL_PORT_2 to any value, then you will get a MYSERIAL1, but it will be used for Gcode. If you need to use a serial port for something else, then you must instantiate the template yourself with your own name, so you will get exclusive access to the serial port you need Look at the bottom of MarlinSerial.h and at the bottom of MarlinSerial.cpp for an example of the required things for it to work |
Great. Thanks for the info. I'll see if I can figure it out. |
This pull request implements templatized Serial classes, allowing to instance them more than once, one for each required hardware serial port, and keeping the static nature of functions (no virtual overhead)
It is implemented for both AVR and Due platforms.
Any suggestion, question, improvement, just ask!
I have tested them lightly, and they work. The logic is exactly the same as before