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 af393fd..dfea47f Binary files a/C/C3 Watch/build/main and b/C/C3 Watch/build/main differ diff --git a/C/C3 Watch/build/main_test b/C/C3 Watch/build/main_test old mode 100644 new mode 100755 index 5df50b3..1feb0e5 Binary files a/C/C3 Watch/build/main_test and b/C/C3 Watch/build/main_test differ 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(); }