NetBurner 3.5.7
PDF Version
Simple Timing

Example Path: examples/PlatformSpecific/SAME70/SerialEmptyCallback/SimpleTiming

Serial TX Empty Callback - Simple Timing Example

Supported Platforms:** MODM7AE70, SBE70LC

Purpose

This example demonstrates using the TX empty callback to insert a precise inter-frame delay after a serial transmission completes. This is the pattern needed by protocols like Modbus RTU, where a silent interval of at least 3.5 character times must separate frames on the bus.

The Problem

The NetBurner serial write() functions return when data has been copied into the software FIFO - not when it has been physically transmitted. If you start an inter-frame delay timer immediately after writestring() returns, the timer begins too early (while data is still being shifted out of the UART), and the actual silent period on the wire will be shorter than intended. For timing-sensitive protocols, this can cause framing errors on the receiving end.

How It Works

The TX empty callback fires from the ISR the instant the UART shift register empties - the precise moment the last bit of the last byte has left the TX pin. By waiting for this callback before starting the delay, the silent period is measured from the correct point in time.

The example uses the same simple callback + semaphore pattern as the Simple example:

  • **OS_SEM TxDoneSem** - Posted by the callback; the main loop pends on it.
  • **INTERFRAME_DELAY_TICKS** - The silent period to insert between frames (1 tick in this demo; in production, calculate from baud rate).

Main Loop Sequence

Each iteration sends a pair of frames with a guaranteed silent period between them:

  1. Reset - Unregister callback, reinitialize semaphore, re-register callback.
  2. Send Frame 1 - writestring(fd_serial, "Frame 1 data payload\n").
  3. Wait for TX complete - TxDoneSem.Pend() blocks until the callback confirms all bytes have left the UART hardware.
  4. Inter-frame delay - OSTimeDly(INTERFRAME_DELAY_TICKS). This delay starts after the wire goes idle, so the full silent period is guaranteed.
  5. Reset and send Frame 2 - Same pattern: reset callback state, write, wait for completion.
  6. Report - Print the frame pair count to the console.
  7. Repeat after a one-second pause.

Calculating the Inter-Frame Delay

For Modbus RTU, the required silent period is 3.5 character times. One character at standard Modbus framing (1 start + 8 data + 1 parity + 1 stop = 11 bits) takes:

Baud Rate Character Time 3.5 Characters
9600 1.146 ms 4.01 ms
19200 0.573 ms 2.01 ms
115200 0.095 ms 0.334 ms

Convert to RTOS ticks by dividing by your tick period and rounding up. At the default 20 ticks/sec (50 ms per tick), sub-tick delays round up to 1 tick. For finer granularity, increase the RTOS tick rate or use a hardware timer.

What to Observe

  • The console prints "Sent frame pair N (total frames: M)" each second.
  • On a logic analyzer monitoring the serial TX line, you will see two bursts of data per iteration with a clean silent gap between them. The gap duration is exactly INTERFRAME_DELAY_TICKS measured from the end of the last byte of Frame 1.

Key Takeaway

The callback tells you when the wire is idle - not just when the software buffer accepted your data. This is essential for any protocol that requires precise timing between transmissions.

Next Steps

  • SimpleGPIO - Shows the basic callback pattern for transceiver control (GPIO toggling).
  • Advanced - Shows how to handle multi-write transactions where the callback can fire between writes.
  • SerialTxEmptyTechnicalDetails.md (in parent directory) - Full technical reference covering the hardware pipeline, driver internals, and the callback mechanism.