-
Notifications
You must be signed in to change notification settings - Fork 7.6k
How can I reset Serial2 / UART2? #662
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
Comments
What do you see as errors? Old data? Generally SerialX.begin should reinit the serials. |
Board: ESPRESSIF ESP32-DEVKITC based on ESP-WROOM-32 Hello, After restarting from deepsleep Serial2 runs with a probability of 20%. edited by kurtow: kindly regards |
Hello @me-no-dev , I see a lot of crap This is a communication after one hard reset or powering up the device, using UART2 connected to pins 16 & 17 at 19200 bauds, the first line is a question sent by ESP32 to the serial client and the second line is the response of the client on the serial bus, the numbers before : are the timeline. The data is obtained with an external hardware that sniffs the serial bus. Every line ends with an ACK, client sent ACK to ESP32 and ESP32 send ACK to the client P300138824:031D58C0156F5C 1A P300138839:0300FF00C0F8FD 0A P300141726:031D58C0002DC8 1A P300142151:021D5C05F72D 1A P300142166:026D5C052F25 6A After the OTA update the first command change to this sequence, you can see the same bytes but they are not sent in the correct order, is like they are rotated in the buffer. In these sequences, there is no ACK because they are wrong, ESP tries to send several times without success. P300121672:021D58031D5800 But the bytes read by ESP32 in serial port are wrong too if I read the last sequence with ESP32, I receive 7780: 50006100E58A1A I think there must be some kind of bits in the UART register that becomes 0 after a hard reset, but serial.begin ignores it and cause this issue. Best regards |
Please pull the latest changes and report :) Thanks! |
Hello @me-no-dev, this issue was not solved with the last commit Best regards |
Is the same thing, before the OTA update, with serial 2, the data sent is: P300235436: 021D58C29242 1A After the OTA update, the data is rotated in the serial 2 P300426334: 9242 CA 021D58C2 The CA is the CRC failure, same code different behavior. After a hard reset, the system goes to their normal behavior. Bye |
looks like data comes out of order? |
The command that sent the data is Serial2.printf and I read with an external Arduino. |
that is not really possible ;) Serial.print sends the bytes one by one in a blocking manner |
Upps, not print is write that calls to hardwareSerial.cpp size_t HardwareSerial::write(const uint8_t *buffer, size_t size) that calls to esp32-hal-uart.c void uartWriteBuf(uart_t* uart, const uint8_t * data, size_t len) This function isn't waiting to transmit the byte, while still room in the fifo it is pushing every byte. |
Not sure if it applies equally here but I found that over a reboot, the I2C FSM (state machine) was left in a funny state. I just submitted a pull request to add the reset function for I2C. It does so by calling the following:
For the UART, the same type of operation would be:
or using PERIPH_UART1_MODULE or PERIPH_UART2_MODULE depending on which UART you are using. I had to add code to the I2C HAL layer to do so, had to include the following:
and had to call the I2C initialization code once again after doing so. Doing something similar may be worth trying in your case. |
Thanks @lonerzzz, I try but this does not work for me, There is some change in the behavior in UART2 but still desynchronized bool Dbus2::init(Debug *pdebug){ periph_module_disable(PERIPH_UART2_MODULE); Serial2.begin(19200, SERIAL_8N1); return true; |
One other thing worth looking at is in uartBegin in the file esp32-hal-uart.c. The code there is such that if the queue has been created, it won't be created again so if you were out of sync and the internal queue is unchanged, then you are likely facing some unexpected data right from the start.
It would be worth ensuring that the queue is empty as a part of resetting. |
OK I think it's time you show some code :) both on ESP and AVR ;) |
I'm out for a while. void uartConfiguration(uint8_t uart_nr, char resul, int size) Following the @lonerzzz suggestion I change the uartBegin to delete the oldest structures and I insert this code in uartBegin with no results at all #if !CONFIG_DISABLE_HAL_LOCKS |
Hi @me-no-dev, I'm out for a while, your right but my code is about 10k. I'm going to write a short version that it only checks the trouble so you can try in your esp32 |
We are facing a similar issue with the Serial2 port using the latest (as of yesterday, 30/Oct) arduino-esp32 base. After an Calling If we push the board’s ‘Enable’ button or power cycle the board, no such problems occur. |
@nkostis is this problem related to hardware fifo? It looks to me that there is stale data in the FIFO from before the reboot. The hardware reference describes a 1024 byte FIFO buffer shared between the three UARTS. UART_CONF0_REG.UART_TXFIFO_RST = 1;
UART_CONF0_REG.UART_TXFIFO_RST = 0; A software reset just restarts the processor, a hardware reset initializes the hardware to a know state. It looks to me that the UART is sending old data. |
Hello, I don't think is a problem related to USART hardware, because, if you read the history messages, I made some test and I can't found differences between the machine registers in hardware restart and software restart. ESP32Test2.ino.txt If everything is ok the arduino UNO must receive the sequence 021D58C29242CA, but after the first software reset the received data is corrupted. Eventually after an indeterminate number of resets the sequence it's recovered. My theory is about the software driver and the struct uart, that some variable is not properly initiated, but in a hardware reset this variable is forced to zero by memory behavior. Best regards |
Another detail, this behavior only responds to ESP32 Arduino UART driver, in esp-idf this issue doesn't happen. I translate the code to esp-idf and UART2 works fine after software reset. Best regards |
i don't think it's stale data, as if you don't reboot and continue writing to serial2 everything is fine. It's only after reboot that this happens, which makes me think that this is incorrect FIFO pointers initialization (probably its memory is accessed via a circular queue and not both pointers (head and tail) are initialized?).
Yes, the arduino code for |
Hello, I've found this can be relevant to this issue in esp-idf. |
I propose a change in the Serial.flush function to avoid the trouble with serial2, is very similar to change made in uart.c in esp-idf git esp32-hal-uart.c void uartFlush(uart_t* uart)
// uart->dev->conf0.txfifo_rst = 1; // uart->dev->conf0.rxfifo_rst = 1;
} |
Thanks for the work , I have this issue aswell... Tried adding this code and on first boot the board comes up ok, second boot after a software restart, it just hangs.... any ideas? |
Tried to debug it to find out where its hanging, however serial fails so cant see any printf statements coming out..... Found if I left the old
code in, it doesnt hang, but the serial is still in a mess :( Not the best that serial2 is this unstable! ( the system hangs after its starts Serial and then tries to start Serial2. Thanks |
Hi Phil, I read in another issue that the reason for that behavior, is a hardware failure. It is due to a wrong connection in the internal reset of serial 1 & 2. |
Thanks for the reply. Serial 2 kind of works, but its very unstable, sometimes after boot it works, sometimes characters come in all over the place. Unfortunately I need 3 UARTS in my project running at 115200 :( Did the ESPIDF way of running the uart work ok still ? Will have to move to that :) |
I think the solution will come with the version 2 of the chip because the failure is hardware related and I hope that EXPRESSIF is working to solve it, as other troubles like the inaccuracy of analog reads or the inability of analog2 channels when you are using WiFi. |
Sounds about right ! Did you get the ESPIDF code to run ok however ? I can move one of the ports to that code , thats not an issue, just checking before I go ahead. Unfortunately I need 3 UARTS, one is for gps, one for radio board ( in and out ) and one for comms to a flight instrument ( in and out ) . Alternatively I could add one of the ports to be software serial I guess. Thanks |
I solved this by adding a flush before each send. All 3 my UARTS work now. |
Thanks, sends seem to be better, its reading thats the issue.... and the restart issue :( |
Mmmm maybe I also have this issue. I can not get the MODBUS library to read. I can set a register but can not read one. so maybe the read is the problem. I can send and read on 2 of the UARTS and I can send on all 3 of them. Let me test if I can receive on the 3rd one withou MODBUS. |
I'd thought it was just me! I've been trying to figure this out for a while. Works fine with an external reset but after ESP.restart, serial2 is a mess. I'll try the flush before each send. |
OK I see the same thing on the read. That is why my MODBUS is not working. I can send. But nothing comes back into the read buffer. I can use all 3 UART to send but only 2 will receive data. |
All 3 receive data here.... update your espidf and arduino, that should solve that issue. However, Serial 2 sometimes works ok, then after a software reboot or even sometimes on boot, characters come into the esp in a semi random order, characters missing aswell. Would really appreciate a fix ! :) I tried the fix recommended by jestebanes - however it hangs on boot when Serial 2 is brought up after a software reset. Just tested this directly in code by adding a GPS to the esp32 - assigning serial 1 to the gps RX pin, datra comes in with no corruption at all, then switching to Serial 2, data is corrupted, same pins, same GPS. Unfortunately I really need Serial2 ! Anyone ? :) |
Tried using the flush statement before every read or write, first 2 reboots it worked perfectly, and then data corruption came back on the third reboot. Next reboot, data is ok again and then all corruption is back again.... Surely this needs looking into ASAP - serial ports are kind of fundamental to a chip ! :) |
I have a similar problem with UART2. The RX ringbuffer (and/or) FIFO behaves strange once the buffer flew over. I did not manage to get out of this condition (uart_flush and even esp_restart does not help). I found out that going to deep sleep and waking up after a second does help (i.e. esp_deep_sleep(1000*1000))! |
@thomasschalch did you try the workaround #1189 ? |
@JacoFourie thanks for your reply! I'm using esp-idf v3.0-rc1 without arduino libraries. The mentioned issue is already fixed there. |
Yes in the workaround we use the code from the ESPIDF fix and apply it to the wrapper. |
The above modification in esp32-hal-uart.c didn't help me :( I had the same issue and I read somewhere that using ESP-IDF uart API works fine. So, I tried to implement my HardwareSerial using ESP-IDF API and this really works, you can do ESP.restart() and UART2 works after software reset. I pushed my implementation called ESP32Serial here https://github.com/9a4gl/ESP32Serial |
Hardware:
Board: Own design based on ESP-WROOM-32
Core Installation/update date: 23/sept/2017
IDE name: Arduino IDE
SDK version: v3.0-dev-745-gc4e65d6a
Flash Frequency: 80Mhz
Upload Speed: 512000
Description:
I am using OTA to upgrade my firmware but after a software update Serial2 doesn't work properly
Apparently, if I make a hardware reset, the serial port works fine but if ESP.restart() is used the serial port doesn't work.
Doing a little investigation, ESP.restart call to esp_restart(); defined in system.h and I found, the library header. Then the problem is clear UART1 and UART2 weren't reset.
how can I reset those UARTs?
/**
*/
void esp_restart(void) attribute ((noreturn));
Best wishes
The text was updated successfully, but these errors were encountered: