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

Avoid blocking main loop while sending data via UART #10

Open
mstrens opened this issue Mar 23, 2019 · 6 comments
Open

Avoid blocking main loop while sending data via UART #10

mstrens opened this issue Mar 23, 2019 · 6 comments
Labels
bug Something isn't working help wanted Extra attention is needed

Comments

@mstrens
Copy link

mstrens commented Mar 23, 2019

I had at look at the way data are sent via UART.
I found this code
#ifndef USEUSB
USART_SendData(USART1, data);
while (!(USART1->SR & USART_FLAG_TXE));
return;
#endif
It means that the CPU waits in the "while" loop when a byte is written in UART if the UART is still sending a previous byte.
So if several bytes have to be sent (e.g in case of error, alarm or on reply on "?") the CPU will be blocked (waiting) several times for about max 100 micro sec per char).
During this time, the cpu can not plan new motions.
I presume it should be better to write the data to be sent in a buffer and to use an interrupt to send the buffer without blocking the main loop.

@robomechs
Copy link
Owner

Ok. We can use dma for this purpose.

@mstrens
Copy link
Author

mstrens commented Mar 23, 2019

Is it possible to use DMA when you do not yet know the number of char to be sent?
I presume, the logic is currently to call "serial_write()" byte per byte from many place in the code.
Is it not easier to fill a buffer and use an interrupt to sent the data in the buffer?

@robomechs
Copy link
Owner

Maybe. We have to think.

@robomechs robomechs added bug Something isn't working help wanted Extra attention is needed labels Mar 30, 2019
@mstrens
Copy link
Author

mstrens commented Mar 31, 2019

I changed the code in order to toggle a pin each time the program goes into the main loop (in protocol.c). I put a digital scope on the serial RX and TX signal and on this pin.
I can confirm that when GRBL is sending the status (in reply to a "?"), the STM32 does not enter anymore the main loop for about 3.2 ms.
This delay would not exist if sending via UART would use a buffer and an interrupt

@mstrens
Copy link
Author

mstrens commented Mar 31, 2019

I made changes in order to use interrupts when sending data via UART (in order to avoid locking the main loop).
Code concerns main.c, serial.c and serial.h
I tested the code with UART and it seems OK.
Code is available on my site (in branch master)
https://github.com/mstrens/grbl_6axis_on_stm32
In this code there are also some changes in order to check the timing of the protocol_main_loop (in protocol.c) and the timing of handling the set/dir in interrupts (in stepper). The principe is to change the pin flood and mist (just for debug). It is activated in protocol.c with parameter
#define DEBUG_TIMING_WITH_FLOOD_AND_MIST

@mstrens
Copy link
Author

mstrens commented Apr 1, 2019

I made a new change in order to put #define DEBUG_TIMING_WITH_FLOOD_AND_MIST in grbl.h (instead of protocol.c; it was wrong).
I also now change the flood pin when I change the X step pin (it is for my current testing).
it could even change for future test. So look at the code if you want to use such a debug function

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants