Skip to content

Conversation

@bessman
Copy link
Contributor

@bessman bessman commented Oct 24, 2025

This PR adds UART_enable_passthrough and UART_disable_passthrough to system/bus/uart. In passthrough mode, all data received on either bus is forwarded and output on the other.

Summary by Sourcery

Introduce UART passthrough mode to forward received data between two UART buses, with enable/disable APIs and safety guards.

New Features:

  • Add UART_enable_passthrough and UART_disable_passthrough to forward data between two UART handles in bi-directional passthrough mode

Enhancements:

  • Extend UART_Handle with passthrough_target and prevent deinitialization while passthrough is active
  • Swap and restore internal TX/RX buffers during passthrough setup and teardown

Documentation:

  • Document passthrough APIs and usage notes in uart.h

Tests:

  • Add comprehensive unit tests for passthrough enable/disable, error cases, and data flow in both directions

@sourcery-ai
Copy link

sourcery-ai bot commented Oct 24, 2025

Reviewer's Guide

This PR introduces a UART passthrough mode by extending the UART handle, adding global state to manage disabled buffers, and implementing enable/disable functions that swap the underlying RX/TX buffers and install a passthrough callback to forward data between two UART buses.

Sequence diagram for UART passthrough data forwarding

sequenceDiagram
participant "UART_Handle 1"
participant "UART_Handle 2"
participant "passthrough_callback()"
"UART_Handle 1"->>passthrough_callback(): Data received
passthrough_callback()->>"UART_Handle 2": start_transmission()
"UART_Handle 2"->>"UART_Handle 1": Data forwarded
Loading

Class diagram for updated UART_Handle and passthrough functions

classDiagram
class UART_Handle {
    int bus_id
    CircularBuffer* rx_buffer
    CircularBuffer* tx_buffer
    UART_RxCallback rx_callback
    uint32_t rx_threshold
    bool initialized
    UART_Handle* passthrough_target
}
class CircularBuffer
class UART_RxCallback
UART_Handle --> CircularBuffer : uses rx_buffer
UART_Handle --> CircularBuffer : uses tx_buffer
UART_Handle --> UART_RxCallback : uses rx_callback
UART_Handle --> UART_Handle : passthrough_target
class UART {
    +UART_enable_passthrough(UART_Handle* handle1, UART_Handle* handle2)
    +UART_disable_passthrough(UART_Handle* handle1, UART_Handle* handle2)
}
UART ..> UART_Handle : operates on
UART ..> CircularBuffer : manages disabled tx_buffers
Loading

Flow diagram for enabling UART passthrough

flowchart TD
A["UART_enable_passthrough(handle1, handle2)"] --> B["Check if passthrough already active"]
B -->|No| C["Check if handles are initialized"]
C -->|Yes| D["Store original tx_buffers"]
D --> E["Swap tx_buffer and rx_buffer between handles"]
E --> F["Set passthrough_target for each handle"]
F --> G["Install passthrough_callback as rx_callback"]
B -->|Yes| H["THROW(ERROR_RESOURCE_BUSY)"]
C -->|No| I["THROW(ERROR_DEVICE_NOT_READY)"]
Loading

File-Level Changes

Change Details Files
Extended UART handle and global state for passthrough
  • Added passthrough_target field to UART_Handle
  • Introduced g_disabled_tx_buffers array to store temporarily disabled TX buffers
  • Initialized passthrough_target to nullptr in UART_init
src/system/bus/uart.c
src/system/bus/uart.h
tests/test_headers/opaque.h
Guard deinitialization when passthrough is active
  • Added a check in UART_deinit to throw ERROR_RESOURCE_BUSY if passthrough_target is set
  • Documented in the header that deinit is forbidden during active passthrough
src/system/bus/uart.c
src/system/bus/uart.h
Implement enable/disable passthrough API
  • Created UART_enable_passthrough with error checks, buffer swapping, target assignment, and RX callback installation
  • Created UART_disable_passthrough to restore original buffers, clear targets, and remove callbacks
  • Enforced single active passthrough pair
src/system/bus/uart.c
src/system/bus/uart.h
Added passthrough callback logic
  • Implemented static passthrough_callback that triggers DMA TX on the target handle
  • Hooked passthrough_callback via UART_set_rx_callback during enable
src/system/bus/uart.c
Expanded unit tests for passthrough scenarios
  • Added tests for successful enable/disable and error cases (null handles, invalid pair, already active)
  • Added tests verifying unidirectional and bidirectional data flow through passthrough
  • Added deinit-with-active-passthrough test
tests/test_uart.c
tests/test_headers/opaque.h

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey there - I've reviewed your changes - here's some feedback:

  • enable_passthrough should validate that the two handles are distinct (i.e. not the same instance) to avoid self-passthrough edge cases.
  • Currently enable_passthrough/disble_passthrough drops any existing RX callback and threshold; consider saving/restoring those so user callbacks aren’t permanently lost.
  • The global g_disabled_tx_buffers relies on calling disable_passthrough in the same handle order; storing original TX buffers in each handle would let you restore them regardless of argument order.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- enable_passthrough should validate that the two handles are distinct (i.e. not the same instance) to avoid self-passthrough edge cases.
- Currently enable_passthrough/disble_passthrough drops any existing RX callback and threshold; consider saving/restoring those so user callbacks aren’t permanently lost.
- The global g_disabled_tx_buffers relies on calling disable_passthrough in the same handle order; storing original TX buffers in each handle would let you restore them regardless of argument order.

## Individual Comments

### Comment 1
<location> `tests/test_uart.c:483-492` </location>
<code_context>
+void test_UART_enable_passthrough_success(void)
</code_context>

<issue_to_address>
**suggestion (testing):** Missing test for enabling passthrough when one or both handles are uninitialized.

Please add a test where a handle is non-null but uninitialized, and confirm that ERROR_DEVICE_NOT_READY is thrown.
</issue_to_address>

### Comment 2
<location> `tests/test_uart.c:589-532` </location>
<code_context>
+void test_UART_passthrough_data_flow_bus0_to_bus1(void)
</code_context>

<issue_to_address>
**suggestion (testing):** Missing test for data overflow in passthrough mode.

Please add a test that simulates RX buffer overflow and verifies passthrough mode maintains data integrity.
</issue_to_address>

### Comment 3
<location> `tests/test_uart.c:864-873` </location>
<code_context>
+void test_UART_disable_passthrough_invalid_pair(void)
</code_context>

<issue_to_address>
**suggestion (testing):** Missing test for disabling passthrough with null handles.

Please add a test to ensure disabling passthrough with null handles returns ERROR_INVALID_ARGUMENT or the correct error.
</issue_to_address>

### Comment 4
<location> `tests/test_uart.c:1018-532` </location>
<code_context>
+void test_UART_deinit_with_active_passthrough(void)
</code_context>

<issue_to_address>
**suggestion (testing):** Missing test for deinit on the second handle while passthrough is active.

Please add a test to confirm that deinit on handle2 throws ERROR_RESOURCE_BUSY when passthrough is active.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment on lines +864 to +850
void test_UART_disable_passthrough_invalid_pair(void)
{
// Arrange - Initialize three UART buses
CircularBuffer rx_buffer1, tx_buffer1;
CircularBuffer rx_buffer2, tx_buffer2;
CircularBuffer rx_buffer3, tx_buffer3;
uint8_t rx_data1[256], tx_data1[256];
uint8_t rx_data2[256], tx_data2[256];
uint8_t rx_data3[256], tx_data3[256];

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): Missing test for disabling passthrough with null handles.

Please add a test to ensure disabling passthrough with null handles returns ERROR_INVALID_ARGUMENT or the correct error.

UART_LL_set_tx_complete_callback_Ignore();

UART_deinit(handle1);
UART_deinit(handle2);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion (testing): Missing test for deinit on the second handle while passthrough is active.

Please add a test to confirm that deinit on handle2 throws ERROR_RESOURCE_BUSY when passthrough is active.

@bessman bessman force-pushed the feat/uart_passthrough branch from deca450 to ddc48f1 Compare October 27, 2025 13:17
@bessman bessman merged commit 43b35cb into fossasia:main Oct 27, 2025
5 checks passed
@bessman bessman deleted the feat/uart_passthrough branch October 27, 2025 13:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant