Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/esp32p4-smv-injector.yml
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,9 @@ jobs:
grep -qx 'CONFIG_AR_PTP_DOMAIN=0' sdkconfig
grep -qx 'CONFIG_AR_PTP_TRANSPORT_SPECIFIC=0' sdkconfig
grep -qx 'CONFIG_AR_PTP_RESPOND_PDELAY=y' sdkconfig
grep -qx 'CONFIG_AR_PTP_VLAN=y' sdkconfig
grep -qx 'CONFIG_AR_PTP_VLAN_ID=0' sdkconfig
grep -qx 'CONFIG_AR_PTP_VLAN_PRIORITY=4' sdkconfig
grep -qx 'CONFIG_AR_PTP_SYNC_INTERVAL_MS=1000' sdkconfig
grep -qx 'CONFIG_AR_PTP_ANNOUNCE_INTERVAL_MS=1000' sdkconfig
echo 'Production timing profile: PASS · serialized shared EMAC TX · PTP-P2 LAB_SOURCE · HW timestamp adapter compiled'
Expand Down
4 changes: 2 additions & 2 deletions apps/arstack_studio/qml/PtpExpertPanel.qml
Original file line number Diff line number Diff line change
Expand Up @@ -545,8 +545,8 @@ SurfacePanel {
NumericField { id: announceField; visible: modeCombo.currentIndex !== 0; theme: panel.theme; monoFont: panel.uiFont; text: "1000"; validator: IntValidator { bottom: 100; top: 10000 } }
Label { text: "Sync interval (ms)"; visible: modeCombo.currentIndex !== 0; color: panel.theme.muted; font.family: panel.uiFont; font.pixelSize: 9 }
NumericField { id: syncField; visible: modeCombo.currentIndex !== 0; theme: panel.theme; monoFont: panel.uiFont; text: "1000"; validator: IntValidator { bottom: 20; top: 5000 } }
StudioDarkCheckBox { id: vlanCheck; theme: panel.theme; uiFont: panel.uiFont; text: "VLAN" }
NumericField { id: vlanField; enabled: vlanCheck.checked; theme: panel.theme; monoFont: panel.uiFont; text: "100"; validator: IntValidator { bottom: 1; top: 4094 } }
StudioDarkCheckBox { id: vlanCheck; theme: panel.theme; uiFont: panel.uiFont; text: "VLAN"; checked: true }
NumericField { id: vlanField; enabled: vlanCheck.checked; theme: panel.theme; monoFont: panel.uiFont; text: "0"; validator: IntValidator { bottom: 0; top: 4094 } }
Label { text: "VLAN PCP"; color: panel.theme.muted; font.family: panel.uiFont; font.pixelSize: 9 }
NumericField { id: pcpField; enabled: vlanCheck.checked; theme: panel.theme; monoFont: panel.uiFont; text: "4"; validator: IntValidator { bottom: 0; top: 7 } }
Label {
Expand Down
3 changes: 1 addition & 2 deletions apps/arstack_studio/src/DeviceController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1350,8 +1350,7 @@ QString DeviceController::ptpConfigCommand(const QVariantMap& profile) {
!parse("vlanPriority", 7U, pcp) ||
!parse("announceIntervalMs", 10000U, announce) ||
!parse("syncIntervalMs", 5000U, sync) ||
announce < 100U || sync < 20U ||
(profile.value(QStringLiteral("vlanEnabled")).toBool() && vlan == 0U)) {
announce < 100U || sync < 20U) {
return {};
}
return QStringLiteral("PTP CONFIG %1 %2 %3 %4 %5 %6 %7 %8")
Expand Down
10 changes: 5 additions & 5 deletions embedded/esp32p4_smv_injector/main/Kconfig.projbuild
Original file line number Diff line number Diff line change
Expand Up @@ -134,14 +134,14 @@ config AR_PTP_PORT_NUMBER
depends on AR_PTP_LAB_TX

config AR_PTP_VLAN
bool "Tag PTP traffic with IEEE 802.1Q VLAN"
default n
bool "Tag PTP traffic with IEEE 802.1Q VLAN (Power Profile PCP4/VID0)"
default y
depends on AR_PTP_LAB_TX

config AR_PTP_VLAN_ID
int "PTP VLAN ID"
range 1 4094
default 100
int "PTP VLAN ID (0 means 802.1Q priority tag)"
range 0 4094
default 0
depends on AR_PTP_LAB_TX && AR_PTP_VLAN

config AR_PTP_VLAN_PRIORITY
Expand Down
4 changes: 3 additions & 1 deletion embedded/esp32p4_smv_injector/sdkconfig.defaults
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ CONFIG_AR_PTP_OPERATING_ROLE=0
CONFIG_AR_PTP_DOMAIN=0
CONFIG_AR_PTP_TRANSPORT_SPECIFIC=0
CONFIG_AR_PTP_PORT_NUMBER=1
# CONFIG_AR_PTP_VLAN is not set
CONFIG_AR_PTP_VLAN=y
CONFIG_AR_PTP_VLAN_ID=0
CONFIG_AR_PTP_VLAN_PRIORITY=4
Comment on lines +31 to +33

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Update documented PTP default to tagged VLAN 0

When operators use this production firmware, it now emits PCP 4/VID 0 tagged PTP, but the published defaults still state that PTP is untagged in docs/PTP_LAB_TIMING.md:123-142 and docs/SMV_STUDIO_V0.1.1_PTP_PRODUCTION.md:9-18. This can lead bench configurations and capture expectations to omit the required priority tag, so the documented production defaults should be updated with this configuration change.

Useful? React with 👍 / 👎.

CONFIG_AR_PTP_ANNOUNCE_INTERVAL_MS=1000
CONFIG_AR_PTP_SYNC_INTERVAL_MS=1000
CONFIG_AR_PTP_RESPOND_PDELAY=y
Expand Down
7 changes: 4 additions & 3 deletions include/ariec61850/time_sync/ptp_runtime.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,10 @@ class PtpPublisherRuntime final {
error = "VLAN priority must be 0..7";
return false;
}
if (options.vlan_id.has_value() &&
(*options.vlan_id == 0U || *options.vlan_id > 4094U)) {
error = "VLAN ID must be 1..4094";
// IEEE 802.1Q priority-tagged VLAN 0 / PCP 4 is the Power
// Utility Profile default. 4095 is reserved; VID 0 is valid.
if (options.vlan_id.has_value() && *options.vlan_id > 4094U) {
error = "VLAN ID must be 0..4094";
return false;
}
if (options.port_number == 0U) {
Expand Down
26 changes: 26 additions & 0 deletions tests/test_ptp_power_profile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,31 @@ void check_source_heartbeat_freshness_and_time_provenance() {
explicit_offset.stop();
}

void check_priority_tagged_power_profile_wire() {
auto options = make_source();
options.vlan_id = std::uint16_t{0U};
options.vlan_priority = 4U;
std::string error;
REQUIRE(PtpPublisherRuntime::validate_options(options, error));
PtpPublisherRuntime source{options};
REQUIRE(source.start());
const auto announce = source.prepare_announce(PtpTimestamp{1000U, 0U});
REQUIRE(announce.has_value());
const auto& raw = announce->ethernet_frame;
REQUIRE(raw.size() > 18U);
REQUIRE(raw[12] == 0x81U && raw[13] == 0x00U);
REQUIRE(raw[14] == 0x80U && raw[15] == 0x00U); // PCP4, VID0
REQUIRE(raw[16] == 0x88U && raw[17] == 0xF7U);
PtpFrame parsed{};
REQUIRE(PtpCodec::try_parse_ethernet_frame(raw, parsed));
REQUIRE(parsed.vlan_id.has_value());
REQUIRE(*parsed.vlan_id == static_cast<std::uint16_t>(0U));
REQUIRE(parsed.header.message_type == PtpMessageType::announce);
source.stop();
options.vlan_id = std::uint16_t{4095U};
REQUIRE(!PtpPublisherRuntime::validate_options(options, error));
}

void check_ptp_wire_sequence_and_identity() {
auto options = make_source();
constexpr std::uint8_t domain = 93U; // supported alternate network domain
Expand Down Expand Up @@ -309,6 +334,7 @@ int main() {
check_source_readiness_requires_fresh_wire_proof();
check_source_heartbeat_freshness_and_time_provenance();
check_ptp_wire_sequence_and_identity();
check_priority_tagged_power_profile_wire();
check_vlan_encoding_remains_configurable();
check_tai_seed_and_truthful_time_properties();
std::cout << "PTP Power Profile wire and configuration checks passed\n";
Expand Down
Loading