From bf8924f664c5020a398e36676fb5a4b088109e79 Mon Sep 17 00:00:00 2001 From: Rens Pastoor <555408@student.fontys.nl> Date: Fri, 6 Jun 2025 15:45:20 +0200 Subject: [PATCH] watch finished v1 --- .vscode/settings.json | 4 +- C/C3 Watch/build/main | Bin 45416 -> 50056 bytes C/C3 Watch/build/main_test | Bin 56112 -> 63552 bytes C/C3 Watch/shared/watch_registers.c | 147 +++++++++------ C/C3 Watch/shared/watch_registers.h | 2 +- C/C3 Watch/test/watch_registers_test.c | 250 ++++++++++++++++++++++--- 6 files changed, 319 insertions(+), 84 deletions(-) mode change 100644 => 100755 C/C3 Watch/build/main mode change 100644 => 100755 C/C3 Watch/build/main_test diff --git a/.vscode/settings.json b/.vscode/settings.json index 9f2aa53..e600f1c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,7 +1,9 @@ { "files.associations": { "decode.h": "c", - "unity_test_module.h": "c" + "unity_test_module.h": "c", + "cstdint": "c", + "cstdlib": "c" }, "cmake.sourceDirectory": "/home/rens/files/T2/HC/holyc-lang/src" } \ No newline at end of file diff --git a/C/C3 Watch/build/main b/C/C3 Watch/build/main old mode 100644 new mode 100755 index af393fd49a0532ef45d0b8a929fbba405dc904ae..dfea47f8bed92f6174072698a6b16ba387f0d74f GIT binary patch delta 13024 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 delta 21817 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 C=?`82 diff --git a/C/C3 Watch/shared/watch_registers.c b/C/C3 Watch/shared/watch_registers.c index 6e4897f..17136a7 100644 --- a/C/C3 Watch/shared/watch_registers.c +++ b/C/C3 Watch/shared/watch_registers.c @@ -3,64 +3,105 @@ // leave resource_detector.h as last include! #include "resource_detector.h" -void watch_registers_toggle_config_is_paused(uint8_t* config) -{ +void watch_registers_toggle_config_is_paused(uint8_t* config){ + if (config == NULL) return; + *config ^= 0x08; // Toggle the 4th bit 0x08 = 0b00001000 +} +void watch_registers_set_config_time_format(uint8_t* config, time_format format){ + uint8_t tf; + if (config == NULL) return; + if (format == TIME_HOUR_MINUTE) { + tf = 0x00; + } else if (format == TIME_HOUR_MINUTE_SECOND) { + tf = 0x01; + } + *config = (*config & 0x0E) | tf; +} +void watch_registers_set_config_time_update_interval(uint8_t* config, time_update_interval interval){ + uint8_t mask; + if (config == NULL) return; + if (interval == TIME_UPDATE_DISABLED){ + mask = 0x00; + } else if (interval == TIME_EVERY_1_SECOND){ + mask = 0x01; + } else if (interval == TIME_EVERY_30_SECONDS){ + mask = 0x02; + } else if (interval == TIME_EVERY_MINUTE){ + mask = 0x03; + } + *config = (*config & 0xF9) | (mask << 1); // Clear bits 2 and 3 and set them to the new value: 0x06 = 0b00000110 +} +void watch_registers_get_config_settings(uint8_t config, bool* is_paused, time_format* format, time_update_interval* interval){ + if (format == NULL || is_paused == NULL || interval == NULL) return; //null check + if ((config & 0x08) != 0) { + *is_paused = true; // Check if the 4th bit is set + } else if ((config & 0x08) == 0) { + *is_paused = false; + } + *format = (time_format)(config & 0x01); + *interval = (time_update_interval)((config >> 1) & 0x03); } -void watch_registers_set_config_time_format(uint8_t* config, time_format format) -{ +void watch_registers_set_time_hours(uint8_t* time_bits_low, uint8_t* time_bits_high, uint8_t hours){ + if (time_bits_low == NULL || time_bits_high == NULL) return; //null check + if (hours > 11) { + hours = 11; + }else if (hours < 0) { + hours = 0; + } + *time_bits_high = (*time_bits_high & 0x0F) | ((hours & 0x0F) << 4); // Set the upper nibble +} +void watch_registers_set_time_minutes(uint8_t* time_bits_low, uint8_t* time_bits_high, uint8_t minutes){ + if (time_bits_low == NULL || time_bits_high == NULL) return; //null check + if (minutes > 59) { + minutes = 59; + } // if minutes < 0, isnt needed becouse uint8_t cannot be negative + *time_bits_high = (*time_bits_high & 0xF0) | ((minutes >> 2) & 0x0F); // Set the lower nibble of MSB + *time_bits_low = (*time_bits_low & 0x3F) | ((minutes & 0x03) << 6); // Set the upper two bits of LSB +} +void watch_registers_set_time_seconds(uint8_t* time_bits_low, uint8_t* time_bits_high, uint8_t seconds){ + if (time_bits_low == NULL || time_bits_high == NULL) return; //null check + if (seconds > 59) { + seconds = 59; + } // if seconds < 0, isnt needed becouse uint8_t cannot be negative + *time_bits_low = (*time_bits_low & 0xC0) | (seconds & 0x3F); // Set the lower 6 bits of LSB +} +void watch_registers_get_time(uint8_t time_bits_low, uint8_t time_bits_high, uint8_t* hours, uint8_t* minutes, uint8_t* seconds){ + if (hours == NULL || minutes == NULL || seconds == NULL) return; //null check + *hours = (time_bits_high >> 4) & 0x0F; + *minutes = ((time_bits_high & 0x0F) << 2) | ((time_bits_low >> 6) & 0x03); + *seconds = time_bits_low & 0x3F; } -void watch_registers_set_config_time_update_interval( - uint8_t* config, time_update_interval interval) -{ +void watch_registers_set_date_year(uint8_t* date_bits_low, uint8_t* date_bits_high, uint8_t year){ + if (date_bits_low == NULL || date_bits_high == NULL) return; //null check + if (year > 127) { + year = 127; // Maximum year value is 127 (0x7F) for 7 bits + } // if year < 0, isnt needed becouse uint8_t cannot be negative + *date_bits_low = (*date_bits_low & 0x80) | (year & 0x7F); // Set the lower 2 bits of LSB } - -void watch_registers_get_config_settings( - uint8_t config, bool* is_paused, time_format* format, - time_update_interval* interval) -{ +void watch_registers_set_date_month(uint8_t* date_bits_low, uint8_t* date_bits_high, uint8_t month){ + if (date_bits_low == NULL || date_bits_high == NULL) return; //null check + if (month > 12) { + month = 12; // Maximum month value is 12 + } else if (month < 1) { + month = 1; // Minimum month value is 1 + } + *date_bits_high = (*date_bits_high & 0xF8) | ((month >> 1) & 0x07); + *date_bits_low = (*date_bits_low & 0x7F) | ((month & 0x01) << 7); } - -void watch_registers_set_time_hours( - uint8_t* time_bits_low, uint8_t* time_bits_high, uint8_t hours) -{ +void watch_registers_set_date_day_of_month(uint8_t* date_bits_low, uint8_t* date_bits_high,uint8_t day_of_month){ + if (date_bits_low == NULL || date_bits_high == NULL) return; //null check + if (day_of_month > 31) { + day_of_month = 31; // Maximum day of month value is 31 + } else if (day_of_month < 1) { + day_of_month = 1; // Minimum day of month value is 1 + } + *date_bits_high = (*date_bits_high & 0x07) | ((day_of_month & 0x1F) << 3); // Set the upper 5 bits of MSB } - -void watch_registers_set_time_minutes( - uint8_t* time_bits_low, uint8_t* time_bits_high, uint8_t minutes) -{ -} - -void watch_registers_set_time_seconds( - uint8_t* time_bits_low, uint8_t* time_bits_high, uint8_t seconds) -{ -} - -void watch_registers_get_time( - uint8_t time_bits_low, uint8_t time_bits_high, uint8_t* hours, - uint8_t* minutes, uint8_t* seconds) -{ -} - -void watch_registers_set_date_year( - uint8_t* date_bits_low, uint8_t* date_bits_high, uint8_t year) -{ -} - -void watch_registers_set_date_month( - uint8_t* date_bits_low, uint8_t* date_bits_high, uint8_t month) -{ -} - -void watch_registers_set_date_day_of_month( - uint8_t* date_bits_low, uint8_t* date_bits_high, - uint8_t day_of_month) -{ -} - -void watch_registers_get_date( - uint8_t date_bits_low, uint8_t date_bits_high, uint8_t* year, - uint8_t* month, uint8_t* day_of_month) -{ +void watch_registers_get_date(uint8_t date_bits_low, uint8_t date_bits_high, uint8_t* year, uint8_t* month, uint8_t* day_of_month){ + if (year == NULL || month == NULL || day_of_month == NULL) return; //null check + *year = date_bits_low & 0x7F; // Get the lower 7 bits of LSB + *month = ((date_bits_high & 0x07) << 1) | ((date_bits_low >> 7) & 0x01); // Get the upper 3 bits of MSB and the lower bit of LSB + *day_of_month = (date_bits_high >> 3) & 0x1F; // Get the upper 5 bits of MSB } diff --git a/C/C3 Watch/shared/watch_registers.h b/C/C3 Watch/shared/watch_registers.h index 6693118..d5dc4df 100644 --- a/C/C3 Watch/shared/watch_registers.h +++ b/C/C3 Watch/shared/watch_registers.h @@ -77,7 +77,7 @@ void watch_registers_get_config_settings( * @param time_bits_low: The address to which the updated LSB part of the time will be written. * @param time_bits_high: The address to which the updated MSB part - of the time will be written. + of the time will be written. * @param hours: The hour part of the time. * * @pre time_bits_low and time_bits_high may not be NULL. diff --git a/C/C3 Watch/test/watch_registers_test.c b/C/C3 Watch/test/watch_registers_test.c index 4f95a3d..4b76152 100644 --- a/C/C3 Watch/test/watch_registers_test.c +++ b/C/C3 Watch/test/watch_registers_test.c @@ -1,65 +1,257 @@ #include #include - #include "unity.h" #include "unity_test_module.h" #include "watch_registers.h" - -// leave resource_detector.h as last include! #include "resource_detector.h" -// I rather dislike keeping line numbers updated, so I made my own macro to -// ditch the line number +// I rather dislike keeping line numbers updated, so I made my own macro to ditch the line number #define MY_RUN_TEST(func) RUN_TEST(func, 0) -void watch_setUp(void) -{ +void watch_setUp(void){} +void watch_tearDown(void){} +//config +void test_settings_toggle_config_is_paused(void){ + uint8_t config = 0x00; + watch_registers_toggle_config_is_paused(&config); + TEST_ASSERT_EQUAL(0x08, config); // 0b1000 + watch_registers_toggle_config_is_paused(&config); + TEST_ASSERT_EQUAL(0x00, config); // 0b0000 } - -void watch_tearDown(void) -{ - // This is run after EACH test +void test_setting_set_config_time_format(void){ + uint8_t config = 0x00; + watch_registers_set_config_time_format(&config, TIME_HOUR_MINUTE); + TEST_ASSERT_EQUAL(0x00, config); // 0b0000 + watch_registers_set_config_time_format(&config, TIME_HOUR_MINUTE_SECOND); + TEST_ASSERT_EQUAL(0x01, config); // 0b0001 } +void test_setting_set_config_time_update_interval(void){ + uint8_t config = 0x00; + watch_registers_set_config_time_update_interval(&config, TIME_UPDATE_DISABLED); + TEST_ASSERT_EQUAL(0x00, config); // 0b0000 + watch_registers_set_config_time_update_interval(&config, TIME_EVERY_1_SECOND); + TEST_ASSERT_EQUAL(0x02, config); // 0b0010 + watch_registers_set_config_time_update_interval(&config, TIME_EVERY_30_SECONDS); + TEST_ASSERT_EQUAL(0x04, config); // 0b0100 + watch_registers_set_config_time_update_interval(&config, TIME_EVERY_MINUTE); + TEST_ASSERT_EQUAL(0x06, config); // 0b0110 +} +void test_setting_get_config_settings(void){ + uint8_t config = 0x00; // 0b00000000 so time is updated, time format hour:minute, time refresh not updated + bool is_paused; + time_format format; + time_update_interval interval; -void test_setting_time_hours(void) -{ - const uint8_t hours = 0xA5; - uint8_t time_bits_high = 0xA5; - uint8_t time_bits_low = 0x5A; + watch_registers_get_config_settings(config, &is_paused, &format, &interval); + TEST_ASSERT_EQUAL(false, is_paused); + TEST_ASSERT_EQUAL(TIME_HOUR_MINUTE, format); + TEST_ASSERT_EQUAL(TIME_UPDATE_DISABLED, interval); + + watch_registers_toggle_config_is_paused(&config); + watch_registers_get_config_settings(config, &is_paused, &format, &interval); + TEST_ASSERT_EQUAL(true, is_paused); + + watch_registers_set_config_time_format(&config, TIME_HOUR_MINUTE_SECOND); + watch_registers_get_config_settings(config, &is_paused, &format, &interval); + TEST_ASSERT_EQUAL(TIME_HOUR_MINUTE_SECOND, format); + + watch_registers_set_config_time_update_interval(&config, TIME_EVERY_1_SECOND); + watch_registers_get_config_settings(config, &is_paused, &format, &interval); + TEST_ASSERT_EQUAL(TIME_EVERY_1_SECOND, interval); +} +// +//time +void test_time_set_hours(void){ + const uint8_t hours = 0x04; // 0b10100101, but we will set it to 0xA0 (0b10100000) to fit in the 4 bits + uint8_t time_bits_high = 0; + uint8_t time_bits_low = 0; watch_registers_set_time_hours(&time_bits_low, &time_bits_high, hours); - TEST_ASSERT_EQUAL_HEX8(0x55, time_bits_high); - TEST_ASSERT_EQUAL_HEX8(0x5A, time_bits_low); + TEST_ASSERT_EQUAL(0x40, time_bits_high); // 0b01000000 + TEST_ASSERT_EQUAL(0x00, time_bits_low); // 0b00000000 } - -void test_get_time() -{ - const uint8_t hours = 11; - const uint8_t minutes = 55; - const uint8_t seconds = 42; +void test_time_set_minutes(void){ + const uint8_t minutes = 0x31; // 0b00 110001, but we will set it to 0x3F (0b00111111) to fit in the 6 bits + uint8_t time_bits_high = 0; + uint8_t time_bits_low = 0; + + watch_registers_set_time_minutes(&time_bits_low, &time_bits_high, minutes); + TEST_ASSERT_EQUAL(0x0C, time_bits_high); // 0b0000 1100 + TEST_ASSERT_EQUAL(0x40, time_bits_low); // 0b01 000000 +} +void test_time_set_seconds(void){ + const uint8_t seconds = 0x35; // 0b00 110101 + uint8_t time_bits_high = 0; uint8_t time_bits_low = 0; - uint8_t time_bits_high = 0b00; watch_registers_set_time_seconds(&time_bits_low, &time_bits_high, seconds); - watch_registers_set_time_minutes(&time_bits_low, &time_bits_high, minutes); + TEST_ASSERT_EQUAL(0x00, time_bits_high); + TEST_ASSERT_EQUAL(0x35, time_bits_low); // 0b00 000000 +} +void test_time_get_time(void){ + const uint8_t hours = 0x04; // 0b0100 + const uint8_t minutes = 0x30; // 0b00 110000 + const uint8_t seconds = 0x35; // 0b00 110101 + uint8_t time_bits_low = 0; + uint8_t time_bits_high = 0; + watch_registers_set_time_hours(&time_bits_low, &time_bits_high, hours); + watch_registers_set_time_minutes(&time_bits_low, &time_bits_high, minutes); + watch_registers_set_time_seconds(&time_bits_low, &time_bits_high, seconds); uint8_t h; uint8_t m; uint8_t s; watch_registers_get_time(time_bits_low, time_bits_high, &h, &m, &s); + TEST_ASSERT_EQUAL(hours, h); TEST_ASSERT_EQUAL(minutes, m); TEST_ASSERT_EQUAL(seconds, s); } +// +//date +void test_date_set_year(void){ + const uint8_t year = 0x20; // 0b00100000 + uint8_t date_bits_high = 0; + uint8_t date_bits_low = 0; + watch_registers_set_date_year(&date_bits_low, &date_bits_high, year); + TEST_ASSERT_EQUAL(0x00, date_bits_high); // 0b00000000 + TEST_ASSERT_EQUAL(0x20, date_bits_low); // 0b00100000 +} +void test_date_set_month(void){ + const uint8_t month = 0x05; // 0b0101 + uint8_t date_bits_high = 0; + uint8_t date_bits_low = 0; + watch_registers_set_date_month(&date_bits_low, &date_bits_high, month); + TEST_ASSERT_EQUAL(0x02, date_bits_high); // 0b00000 010 + TEST_ASSERT_EQUAL(0x80, date_bits_low); // 0b1 0000000 +} +void test_date_set_day_of_month(void){ + const uint8_t day_of_month = 0x15; // 0b10101 + uint8_t date_bits_high = 0; + uint8_t date_bits_low = 0; + + watch_registers_set_date_day_of_month(&date_bits_low, &date_bits_high, day_of_month); + TEST_ASSERT_EQUAL(0xA8, date_bits_high); // 0b10101 000 + TEST_ASSERT_EQUAL(0x00, date_bits_low); // 0b0 +} +void test_date_get_date(void){ + const uint8_t year = 0x20; // 0b00100000 + const uint8_t month = 0x05; // 0b0101 + const uint8_t day_of_month = 0x16; // 0b10110 + uint8_t date_bits_high = 0; + uint8_t date_bits_low = 0; + + watch_registers_set_date_year(&date_bits_low, &date_bits_high, year); + watch_registers_set_date_month(&date_bits_low, &date_bits_high, month); + watch_registers_set_date_day_of_month(&date_bits_low, &date_bits_high, day_of_month); + + uint8_t y; + uint8_t m; + uint8_t d; + watch_registers_get_date(date_bits_low, date_bits_high, &y, &m, &d); + + TEST_ASSERT_EQUAL(year, y); + TEST_ASSERT_EQUAL(month, m); + TEST_ASSERT_EQUAL(day_of_month, d); +} +//NULL +void test_all_null(void){ + watch_registers_toggle_config_is_paused(NULL); + watch_registers_set_config_time_format(NULL, TIME_HOUR_MINUTE); + watch_registers_set_config_time_update_interval(NULL, TIME_UPDATE_DISABLED); + watch_registers_get_config_settings(0x00, NULL, NULL, NULL); + + uint8_t time_bits_low = 0; + uint8_t time_bits_high = 0; + watch_registers_set_time_hours(NULL, &time_bits_high, 0x04); + watch_registers_set_time_minutes(&time_bits_low, NULL, 0x30); + watch_registers_set_time_seconds(NULL, &time_bits_high, 0x45); + watch_registers_get_time(time_bits_low, time_bits_high, NULL, NULL, NULL); + + uint8_t date_bits_low = 0; + uint8_t date_bits_high = 0; + watch_registers_set_date_year(NULL, &date_bits_high, 0x20); + watch_registers_set_date_month(&date_bits_low, NULL, 0x05); + watch_registers_set_date_day_of_month(NULL, &date_bits_high, 0x15); + watch_registers_get_date(date_bits_low, date_bits_high, NULL, NULL, NULL); + TEST_ASSERT_TRUE(true); // If we reach this point, the test passed +} +// +//full tests +void test_full_watch_configuration(void) { + uint8_t config = 0x00; + + // Configure watch settings + watch_registers_set_config_time_format(&config, TIME_HOUR_MINUTE_SECOND); + watch_registers_set_config_time_update_interval(&config, TIME_EVERY_1_SECOND); + watch_registers_toggle_config_is_paused(&config); + + // Verify all settings + bool is_paused; + time_format format; + time_update_interval interval; + watch_registers_get_config_settings(config, &is_paused, &format, &interval); + + TEST_ASSERT_EQUAL(true, is_paused); + TEST_ASSERT_EQUAL(TIME_HOUR_MINUTE_SECOND, format); + TEST_ASSERT_EQUAL(TIME_EVERY_1_SECOND, interval); +} +void test_full_datetime_overflow_setup(void) { + uint8_t time_bits_low = 0; + uint8_t time_bits_high = 0; + uint8_t date_bits_low = 0; + uint8_t date_bits_high = 0; + + // Set time to 11:59:59 + watch_registers_set_time_hours(&time_bits_low, &time_bits_high, 0x23); + watch_registers_set_time_minutes(&time_bits_low, &time_bits_high, 0x40); + watch_registers_set_time_seconds(&time_bits_low, &time_bits_high, 0x40); + + // Set date to 31/12/2127 + watch_registers_set_date_year(&date_bits_low, &date_bits_high, 0xC9); + watch_registers_set_date_month(&date_bits_low, &date_bits_high, 0x12); + watch_registers_set_date_day_of_month(&date_bits_low, &date_bits_high, 0x31); + + // Verify time + uint8_t hours, minutes, seconds; + watch_registers_get_time(time_bits_low, time_bits_high, &hours, &minutes, &seconds); + TEST_ASSERT_EQUAL(0x0B, hours); // 11 + TEST_ASSERT_EQUAL(0x3B, minutes); // 59 + TEST_ASSERT_EQUAL(0x3B, seconds); // 59 + + // Verify date + uint8_t year, month, day; + watch_registers_get_date(date_bits_low, date_bits_high, &year, &month, &day); + TEST_ASSERT_EQUAL(0x7F, year); + TEST_ASSERT_EQUAL(0x0C, month); + TEST_ASSERT_EQUAL(0x1F, day); +} +// void run_watch_tests() { - UnityRegisterSetupTearDown( watch_setUp, watch_tearDown); + UnityRegisterSetupTearDown(watch_setUp, watch_tearDown); + MY_RUN_TEST(test_settings_toggle_config_is_paused); + MY_RUN_TEST(test_setting_set_config_time_format); + MY_RUN_TEST(test_setting_set_config_time_update_interval); + MY_RUN_TEST(test_setting_get_config_settings); - MY_RUN_TEST(test_setting_time_hours); - MY_RUN_TEST(test_get_time); + MY_RUN_TEST(test_time_set_hours); + MY_RUN_TEST(test_time_set_minutes); + MY_RUN_TEST(test_time_set_seconds); + MY_RUN_TEST(test_time_get_time); + + MY_RUN_TEST(test_date_set_year); + MY_RUN_TEST(test_date_set_month); + MY_RUN_TEST(test_date_set_day_of_month); + MY_RUN_TEST(test_date_get_date); + + MY_RUN_TEST(test_all_null); + + MY_RUN_TEST(test_full_watch_configuration); + MY_RUN_TEST(test_full_datetime_overflow_setup); UnityUnregisterSetupTearDown(); }