From 494c4bb4d72a879a6093838f4268cdda688298bf Mon Sep 17 00:00:00 2001 From: Krzysztof Mazur Date: Sat, 16 Sep 2017 20:15:14 +0200 Subject: [PATCH 1/2] introduce GCP_PSCHED_SYNC_PHASE In some cases the period may be constant, and only the phase must be adjusted. Signed-off-by: Krzysztof Mazur --- include/gcp.h | 1 + include/p-sched.h | 1 + src/main.c | 7 ++++++- src/p-sched.c | 22 ++++++++++++++++++++++ 4 files changed, 30 insertions(+), 1 deletion(-) diff --git a/include/gcp.h b/include/gcp.h index bcbfdac..4279821 100644 --- a/include/gcp.h +++ b/include/gcp.h @@ -165,5 +165,6 @@ #define GCP_CPSCHED_EVENT_DELAY 0x01b /* microseconds */ #define GCP_CPSCHED_PERIOD_N 0x01c /* position numerator */ #define GCP_CPSCHED_PERIOD_D 0x01d /* position denominator */ +#define GCP_CPSCHED_SYNC_PHASE 0x01e /* position */ #endif diff --git a/include/p-sched.h b/include/p-sched.h index 4596656..3eec499 100644 --- a/include/p-sched.h +++ b/include/p-sched.h @@ -19,6 +19,7 @@ int pevent_start(unsigned int id, unsigned int value); int pevent_start_after(unsigned int id, unsigned int value, unsigned int t, unsigned int pos); int pevent_adjust(unsigned int id, int delta); +int pevent_adjust_phase(unsigned int id, int delta); int pevent_set_period(unsigned int id, unsigned int period); int pevent_get_period(unsigned int id, unsigned int *period); int pevent_set_period_n(unsigned int id, unsigned int n); diff --git a/src/main.c b/src/main.c index 7e02320..b40e31b 100644 --- a/src/main.c +++ b/src/main.c @@ -128,6 +128,11 @@ static int gcp_psched(unsigned int cmd, u32 arg, u32 *resp, pevent_get_period(id, &value); value >>= BITS_PER_INT - GCP_PSCHED_VALUE_BITS; break; + case GCP_CPSCHED_SYNC_PHASE: + ret = pevent_adjust_phase(id, (int)(value << 8) >> 8); + pevent_get_period(id, &value); + value >>= BITS_PER_INT - GCP_PSCHED_VALUE_BITS; + break; case GCP_CPSCHED_PERIOD: value <<= BITS_PER_INT - GCP_PSCHED_VALUE_BITS; if (write) @@ -350,7 +355,7 @@ static void gcp_handle_command(struct tty_struct *tty, cmd = (hdr >> GCP_SEQCMD_CMD_SHIFT) & GCP_SEQCMD_CMD_MASK; if (cmd >= GCP_CPSCHED_SYNC - && cmd <= GCP_CPSCHED_PERIOD_D) { + && cmd <= GCP_CPSCHED_SYNC_PHASE) { ret = gcp_psched(cmd, arg, gcp_resp_frame, t, pos); } else if (cmd == GCP_CADD_EVENT) { ret = gcp_add_event(cmd, arg, gcp_resp_frame); diff --git a/src/p-sched.c b/src/p-sched.c index 452c6e9..c90a051 100644 --- a/src/p-sched.c +++ b/src/p-sched.c @@ -232,6 +232,28 @@ int pevent_adjust(unsigned int id, int delta) return 0; } +int pevent_adjust_phase(unsigned int id, int delta) +{ + struct pevent *p = pevents + id; + unsigned int period; + long maxphase; + + if (id >= NR_PEVENTS) + return -EINVAL; + if (p->mode != PEVENT_POSITION) + return -EINVAL; + + period = p->period; + maxphase = (period + (1 << (PLL_SHIFT + 2)) - 1) >> (PLL_SHIFT + 2); + if (delta > maxphase) + delta = maxphase; + else if (delta < -maxphase) + delta = -maxphase; + + p->offset = delta << PLL_SHIFT; + return 0; +} + int pevent_set_time_period(unsigned int id, unsigned int period) { struct pevent *p = pevents + id; -- 2.14.1