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

[rtl872x] fixes DMA enabled USART flush #2800

Merged
merged 2 commits into from
Aug 12, 2024
Merged

Conversation

technobly
Copy link
Member

Problem

  • Serial2.flush() on P2/Photon2 does not wait for bytes to be emptied from USART buffer on D4 (Serial2 TX), but instead when DMA transfer is complete.

Solution

  • Enable the IRQ used to signal TX buffer FIFO emptied for DMA enabled USARTs (Serial2 on P2/Photon2), along with a new busy_ flag, to assist in waiting long enough for all bytes to be transmitted when busy waiting with Serial2.flush()

Steps to Test

  • Run integration tests TEST=wiring/no_fixture
  • Run fixture test TEST=wiring/serial_loopback2 (with TX jumpered to RX)
  • Run example test app while watching the TX pin for each Serial1/2/3 (TX/D4/MOSI) interface and also the signalPin (A0) on Photon2.
  • Run example test app with Serial1 on M-SoM ensuring the Cellular connection works properly.

Example App

#include "Particle.h"

SYSTEM_MODE(SEMI_AUTOMATIC);
SYSTEM_THREAD(ENABLED);

SerialLogHandler logHandler(LOG_LEVEL_INFO);

// Try them all, signalPin should not go LOW before all bytes are flush()'d
// #define MY_SERIAL Serial1
#define MY_SERIAL Serial2
// #define MY_SERIAL Serial3

// P2/Photon2
// TX = Serial1 TX
// D4 = Serial2 TX
// MOSI = Serial3 TX

const pin_t signalPin = A0;
const int baudRate = 600;

auto TEST_PERIOD_MS = 5000;
auto lastTest = 0;

void runTest();

void setup() {
    pinMode(signalPin, OUTPUT);
    digitalWrite(signalPin, LOW);

    Particle.connect();
    waitFor(Particle.connected, 60000);

    MY_SERIAL.begin(baudRate);
}

void loop() {
    if (millis() - lastTest >= TEST_PERIOD_MS) {
        lastTest = millis();
        runTest();
    }
}

void runTest() {
    digitalWrite(signalPin, HIGH);
    int bufferSize = MY_SERIAL.availableForWrite();
    auto start = millis();

    for (int ii = 0; ii < 64; ii++) {
        char c = 0x20 + ii;
        MY_SERIAL.write(c);
    }
    auto writeComplete = millis();
    MY_SERIAL.flush();
    auto empty = millis();
    digitalWrite(signalPin, LOW);
    Log.info("bufferSize=%d writeComplete=%lu empty=%lu", bufferSize, writeComplete - start, empty - start);
}

References


Completeness

  • User is totes amazing for contributing!
  • Contributor has signed CLA (Info here)
  • Problem and Solution clearly stated
  • Run unit/integration/application tests on device
  • (N/A) Added documentation
  • Added to CHANGELOG.md after merging (add links to docs and issues)

hal/src/rtl872x/usart_hal.cpp Show resolved Hide resolved
hal/src/rtl872x/usart_hal.cpp Outdated Show resolved Hide resolved
hal/src/rtl872x/usart_hal.cpp Outdated Show resolved Hide resolved
hal/src/rtl872x/usart_hal.cpp Show resolved Hide resolved
@technobly technobly force-pushed the fix/p2-serial2-flush branch from dbd1abc to aa55e51 Compare July 16, 2024 18:08
@technobly technobly requested a review from avtolstoy July 16, 2024 19:40
@Kategrode Kategrode added this to the 5.9.0 milestone Jul 29, 2024
@avtolstoy avtolstoy force-pushed the fix/p2-serial2-flush branch from aa55e51 to 81e85fc Compare August 12, 2024 17:22
@avtolstoy avtolstoy merged commit 1a8fc11 into develop Aug 12, 2024
13 checks passed
@avtolstoy avtolstoy deleted the fix/p2-serial2-flush branch August 12, 2024 17:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants