mirror of
https://github.com/espressif/esp-idf.git
synced 2026-09-22 13:01:16 +03:00
fix(esp_eth): use stored base_increment when computing PTP addend
The addend in `emac_hal_ptp_start()` was derived from the floating-point `config->ptp_req_accuracy_ns` instead of the integer `base_increment` register that actually drives the sub-second update. The cast to `uint8_t` loses the fractional part, so the un-corrected addend leaves the PTP clock running off-rate. Example: with a 40 MHz XTAL and the default `req_accuracy_ns = 40`, `base_increment` rounds 85.899 up to 86, leaving the clock +1170 ppm fast — well outside the IEEE 802.1AS neighborRateRatio limit (~±200 ppm), so strict-1AS bridges refuse asCapable. Compute the addend from the stored `base_increment` for both rollover modes: `addend = 2^32 * clk_period_ns / increment_ns`. Measured on ESP32-P4: neighborRateRatio drops from +1147.5 ppm to +4.2 ppm, and asCapable is granted. Co-authored-by: Ondrej Kosta <panzer412@gmail.com>
This commit is contained in:
committed by
Euripedes Rocha
parent
b3b9ebb516
commit
e0becb9e43
@@ -404,12 +404,25 @@ esp_err_t emac_hal_ptp_start(emac_hal_context_t *hal, const emac_hal_ptp_config_
|
||||
int32_t to = 0;
|
||||
/* If you are using the Fine correction method */
|
||||
if (config->upd_method == ETH_PTP_UPDATE_METHOD_FINE) {
|
||||
/**
|
||||
* 2^32 2^32 TsysClk(ns)
|
||||
* Addend = ——————— = —————————————————————————— = 2^32 * ——————————————
|
||||
* ratio SysClk(MHz)/PTPaccur(MHz) Taccur(ns)
|
||||
/*
|
||||
* Compute the addend from the actual integer base_increment written
|
||||
* to hardware, not from the ideal ptp_req_accuracy_ns. Because
|
||||
* base_increment is a uint8_t, the cast truncates the fractional
|
||||
* part, making the real sub-second step differ from the requested
|
||||
* accuracy. This is especially required for IEEE 802.1AS where the
|
||||
* uncorrected rate must already be within 200 ppm (neighborRateRatio)
|
||||
* before Sync messages arrive, so we derive the addend from
|
||||
* the truncated value directly.
|
||||
*/
|
||||
uint32_t base_addend = (1ll << 32) * config->ptp_clk_src_period_ns / config->ptp_req_accuracy_ns;
|
||||
double increment_ns;
|
||||
if (emac_ll_is_ts_digital_roll_set(hal->ptp_regs)) {
|
||||
increment_ns = (double)base_increment;
|
||||
} else {
|
||||
increment_ns = (double)base_increment * 1.0e9 / (double)(1ULL << 31);
|
||||
}
|
||||
uint32_t base_addend = (uint32_t)((double)(1ULL << 32) *
|
||||
config->ptp_clk_src_period_ns /
|
||||
increment_ns);
|
||||
emac_ll_set_ts_addend_val(hal->ptp_regs, base_addend);
|
||||
emac_ll_ts_addend_do_update(hal->ptp_regs);
|
||||
while (!emac_ll_is_ts_addend_update_done(hal->ptp_regs) && to < EMAC_PTP_INIT_TIMEOUT_US) {
|
||||
|
||||
Reference in New Issue
Block a user