|
rcbench
Servo and ESC test bench: panel, IOmcu and shared C
|
PPM (pulse-position modulation): several channels multiplexed onto one pin. More...
#include <stdbool.h>#include <stddef.h>#include <stdint.h>Go to the source code of this file.
Data Structures | |
| struct | ppm_cfg_t |
Macros | |
| #define | PPM_MAX_CHANNELS 8u |
| Eight in a 22.5ms frame is the convention; more fits only by shortening the frame, which is what ppm_cfg_t.frame_us is for. | |
| #define | PPM_MAX_RUNS ((PPM_MAX_CHANNELS + 1u) * 2u) |
| Runs a frame needs: a mark and a space per channel, plus the terminating mark and the sync gap. | |
| #define | PPM_CHANNEL_MIN_US 400u |
| The range a channel is carried in, in microseconds, both ends included. | |
| #define | PPM_CHANNEL_MAX_US 2500u |
| #define | PPM_DEFAULT_MARK_US 300u |
| #define | PPM_DEFAULT_FRAME_US 22500u |
| #define | PPM_SYNC_MIN_US 3000u |
| The shortest gap that is unambiguously a gap. | |
| #define | PPM_CFG_DEFAULT() |
Functions | |
| size_t | ppm_frame (const uint16_t *channel_us, uint8_t channels, const ppm_cfg_t *cfg, uint16_t *runs, size_t max_runs) |
| Lay a frame out as alternating run lengths in microseconds. | |
| uint32_t | ppm_min_frame_us (uint8_t channels, const ppm_cfg_t *cfg) |
The shortest frame that can carry channels channels whatever they are commanded to, in microseconds: every channel at PPM_CHANNEL_MAX_US, plus the terminating mark, plus the smallest gap that is still a gap. | |
PPM (pulse-position modulation): several channels multiplexed onto one pin.
A frame is a run of marks. The time from the start of one mark to the start of the next is one channel's pulse width, so a channel is carried by where its mark falls rather than by how long it is, and the mark itself is a fixed 300us that belongs to no channel. After the last channel comes a terminating mark and then a gap long enough that a receiver cannot mistake it for a channel; that gap is what locates the start of the next frame.
The consequence is that channels and frame rate are not independent. Eight channels at 2000us each already spend 16ms of a 22.5ms frame, and the sync gap is whatever is left. Asking for more channels, longer travel or a faster frame eats the gap, and a frame whose gap has shrunk into the range a receiver reads as a channel does not fail visibly: it decodes as a different number of channels, shifted. So this refuses rather than emits a frame whose sync gap is too short.
The polarity is not decided here. Positive and negative shift are the same frame with the levels exchanged, and on the RP2350 that is a pad inversion rather than a different program.
SPDX-License-Identifier: MIT
| #define PPM_CFG_DEFAULT | ( | ) |
| #define PPM_CHANNEL_MIN_US 400u |
The range a channel is carried in, in microseconds, both ends included.
A width outside it is refused, not clamped.
| #define PPM_SYNC_MIN_US 3000u |
The shortest gap that is unambiguously a gap.
A receiver frames on the first interval longer than any channel can be. The ceiling on a channel is PPM_CHANNEL_MAX_US (2500us), so a gap under about 3ms is one that some receiver will read as a very long channel.
| size_t ppm_frame | ( | const uint16_t * | channel_us, |
| uint8_t | channels, | ||
| const ppm_cfg_t * | cfg, | ||
| uint16_t * | runs, | ||
| size_t | max_runs ) |
Lay a frame out as alternating run lengths in microseconds.
runs receives mark, space, mark, space, ... and ends with the terminating mark and the sync gap, so it always holds an even number of entries and always begins with a mark. A driver toggles the pin at each one and does not need to know which is which.
Returns the number of runs written, or 0 when the frame cannot be built: no channels or too many, a channel shorter than the mark it has to contain, a channel outside PPM_CHANNEL_MIN_US..PPM_CHANNEL_MAX_US, or a sync gap below cfg->sync_min_us once the channels have been paid for.
| channel_us | Pulse width of each channel, in us. |
| channels | Number of channels in channel_us. |
| cfg | Frame timing; NULL takes the defaults. |
| runs | Receives the runs. |
| max_runs | Capacity of runs, in entries. |
| uint32_t ppm_min_frame_us | ( | uint8_t | channels, |
| const ppm_cfg_t * | cfg ) |
The shortest frame that can carry channels channels whatever they are commanded to, in microseconds: every channel at PPM_CHANNEL_MAX_US, plus the terminating mark, plus the smallest gap that is still a gap.
A configuration screen wants this before it offers a frame rate, so the refusal above becomes a range the operator never leaves rather than an error they hit. Returns 0 for a channel count this module cannot carry.
| channels | Number of channels to carry. |
| cfg | Frame timing; NULL takes the defaults. |