diff --git a/lib/libx52/Makefile.am b/lib/libx52/Makefile.am index 7ecac03..ea15b66 100644 --- a/lib/libx52/Makefile.am +++ b/lib/libx52/Makefile.am @@ -30,6 +30,15 @@ x52include_HEADERS = libx52.h # pkg-config files pkgconfig_DATA = libx52.pc +check_PROGRAMS = test_offset + +test_offset_SOURCES = test_offset.c +test_offset_CFLAGS = @LIBUSB_CFLAGS@ +test_offset_LDADD = libx52.la + +LOG_DRIVER = env AM_TAP_AWK='$(AWK)' $(SHELL) $(top_srcdir)/tap-driver.sh +TESTS = test_offset + # Extra files that need to be in the distribution EXTRA_DIST = libx52.h x52_commands.h x52_common.h README.md diff --git a/lib/libx52/test_offset.c b/lib/libx52/test_offset.c new file mode 100644 index 0000000..930a81d --- /dev/null +++ b/lib/libx52/test_offset.c @@ -0,0 +1,69 @@ +/* + * Saitek X52 Pro MFD & LED driver + * Test program for validating offset calculation + * + * Copyright (C) 2020 Nirenjan Krishnan (nirenjan@nirenjan.org) + * + * SPDX-License-Identifier: GPL-2.0-only WITH Classpath-exception-2.0 + */ + +#include +#include +#include +#include "x52_common.h" + +struct test_id { + const char *test_case_id; + int offset_primary; + int offset_secondary; + uint16_t x52_offset; +}; + +const struct test_id test_cases[] = { + {"Etc/UTC+24|Etc/UTC-24", -1440, +1440, 0}, + {"Etc/UTC-24|Etc/UTC+24", +1440, -1440, 0x0400}, // Negative 0 + {"Honolulu|Auckland", -600, +720, 0x0478}, // -2 hours + {"Auckland|Honolulu", +720, -600, 0x0078}, // +2 hours + {"Etc/UTC+12|Etc/UTC-14", -720, +840, 0x078}, // +2 hours + {"Etc/UTC-14|Etc/UTC+12", +840, -720, 0x478}, // -2 hours + {"PDT|UTC", -420, 0, 0x1a4}, // +7 hours + {"UTC|PDT", 0, -420, 0x5a4}, // -7 hours + {"PST|UTC", -480, 0, 0x1e0}, // +8 hours + {"UTC|PST", 0, -480, 0x5e0}, // -8 hours + {"Etc/UTC+12|Etc/UTC-12", -720, +720, 0}, + {"Etc/UTC-12|Etc/UTC+12", +720, -720, 0x0400}, +}; + +#define TC_COUNT (sizeof(test_cases) / sizeof(test_cases[0])) + +void run_test(int tc_id) +{ + struct libx52_device dev; + memset(&dev, 0, sizeof(dev)); + + struct test_id test = test_cases[tc_id]; + + dev.timezone[LIBX52_CLOCK_1] = test.offset_primary; + dev.timezone[LIBX52_CLOCK_2] = test.offset_secondary; + + uint16_t obtained = libx52_calculate_clock_offset(&dev, LIBX52_CLOCK_2, 0); + if (obtained != test.x52_offset) { + printf("not "); + } + printf("ok %d %s\n", tc_id + 1, test.test_case_id); + if (obtained != test.x52_offset) { + // Diagnostics + printf("# Expected: %04x\n", test.x52_offset); + printf("# Observed: %04x\n", obtained); + } +} + +int main() +{ + int i; + + printf("1..%ld\n", TC_COUNT); + for (i = 0; i < TC_COUNT; i++) { + run_test(i); + } +} diff --git a/lib/libx52/x52_common.h b/lib/libx52/x52_common.h index c3e8533..8928a9a 100644 --- a/lib/libx52/x52_common.h +++ b/lib/libx52/x52_common.h @@ -105,5 +105,6 @@ static inline uint32_t tst_bit(uint32_t *value, uint32_t bit) } int _x52_translate_libusb_error(enum libusb_error errcode); +uint16_t libx52_calculate_clock_offset(libx52_device *x52, libx52_clock_id clock, uint16_t h24); #endif /* !defined X52JOY_COMMON_H */ diff --git a/lib/libx52/x52_control.c b/lib/libx52/x52_control.c index 655aca5..e96db59 100644 --- a/lib/libx52/x52_control.c +++ b/lib/libx52/x52_control.c @@ -209,7 +209,7 @@ static int _x52_write_date(libx52_device *x52, uint32_t bit) return rc; } -int _x52_calculate_clock_offset(libx52_device *x52, libx52_clock_id clock, uint16_t h24) +uint16_t libx52_calculate_clock_offset(libx52_device *x52, libx52_clock_id clock, uint16_t h24) { int offset; int negative; @@ -231,7 +231,7 @@ int _x52_calculate_clock_offset(libx52_device *x52, libx52_clock_id clock, uint1 * greater issue is to take the two extreme timezones at -1200 and +1400 * for a difference of +26 hours. The safe bet is to check if the offset * exceeds +/- 1023, and subtract 1440, which will convert the offset of - * +22 to -2 hours, or +26 to +4 hours. + * +22 to -2 hours, or +26 to +2 hours. */ while (offset > 1023) { offset -= 1440; // Subtract 24 hours @@ -272,7 +272,7 @@ static int _x52_write_time(libx52_device *x52, uint32_t bit) uint16_t h24 = !!(x52->time_format[clock]); if (clock != LIBX52_CLOCK_1) { - value = _x52_calculate_clock_offset(x52, clock, h24); + value = libx52_calculate_clock_offset(x52, clock, h24); } else { value = h24 << 15 | (x52->time_hour & 0x7F) << 8 |